Spec-Zone .ru
спецификации, руководства, описания, API
|
Этот раздел обсуждает оптимизацию, известную как сокращение раздела. Базовое понятие
позади сокращения раздела относительно просто, и может быть описано, поскольку "Не сканируют разделы, где не может быть никаких совпадающих значений".
Предположите, что у Вас есть разделенная таблица t1
определенный этим оператором:
CREATE TABLE t1 ( fname VARCHAR(50) NOT NULL, lname VARCHAR(50) NOT NULL, region_code TINYINT UNSIGNED NOT NULL, dob DATE NOT NULL)PARTITION BY RANGE( region_code ) ( PARTITION p0 VALUES LESS THAN (64), PARTITION p1 VALUES LESS THAN (128), PARTITION p2 VALUES LESS THAN (192), PARTITION p3 VALUES LESS THAN MAXVALUE);
Рассмотрите случай, где Вы хотите получить следствия a SELECT
оператор, такой как этот:
SELECT fname, lname, region_code, dob FROM t1 WHERE region_code > 125 AND region_code < 130;
Легко видеть, что ни одна из строк, которые должны быть возвращены, не будет ни в одном из разделов p0
или p3
; то есть, мы должны искать только в разделах
p1
и p2
найти соответствие строк. Делая так, возможно
израсходовать намного меньше времени и усилия в обнаружении соответствия строк, чем был бы обязан сканировать
все разделы в таблице. Это "срезание" ненужных
разделов известно как сокращение. Когда оптимизатор может использовать сокращение
раздела в выполнении этого запроса, выполнение запроса может быть порядком величины быстрее чем тот же самый
запрос против неразделенной таблицы, содержащей те же самые определения столбца и данные.
Оптимизатор может выполнить сокращение всякий раз, когда a WHERE
условие может быть
уменьшено до любого из следующих двух случаев:
partition_column
=
constant
partition_column
IN
(constant1
, constant2
, ..., constantN
)
В первом случае оптимизатор просто оценивает выражение разделения для данного значения, определяет, какой раздел
содержит то значение, и сканирует только этот раздел. Во многих случаях знак "равно" может быть
заменен другим арифметическим сравнением, включая <
,
>
, <=
, >=
, и <>
. Некоторое использование запросов BETWEEN
в
WHERE
пункт может также использовать в своих интересах сокращение раздела. См.
примеры позже в этом разделе.
Во втором случае оптимизатор оценивает выражение разделения для каждого значения в списке, создает список соответствия разделов, и затем сканирует только разделы в этом списке раздела.
MySQL может применить сокращение раздела к SELECT
,
DELETE
,
и UPDATE
операторы. INSERT
операторы в настоящий момент не могут быть сокращены.
Сокращение может также быть применено к малым дальностям, которые оптимизатор может преобразовать в
эквивалентные списки значений. Например, в предыдущем примере, WHERE
пункт может
быть преобразован в WHERE region_code IN (126, 127, 128, 129)
. Затем оптимизатор
может решить, что первые три значения в списке находятся в разделе p1
, оставление
тремя значениями в разделе p2
, и что другие разделы не содержат соответствующих
значений и так не должны искаться то, что соответствовали строки.
В MySQL 5.6 оптимизатор может также выполнить сокращение для WHERE
условия, которые
включают сравнения предыдущих типов на многократных столбцах для таблиц то использование RANGE
COLUMNS
или LIST COLUMNS
разделение.
Этот тип оптимизации может быть применен всякий раз, когда выражение разделения состоит из равенства или
диапазона, который может быть уменьшен до ряда равенств, или когда выражение разделения представляет увеличение
или уменьшение отношения. Сокращение может также быть применено для таблиц, разделенных на a DATE
или DATETIME
столбец, когда выражение разделения использует YEAR()
или TO_DAYS()
функция. Кроме того, в MySQL 5.6, сокращение может быть применено
для таких таблиц, когда выражение разделения использует TO_SECONDS()
функция.
Предположите ту таблицу t2
, определенный как показано здесь, делится на a DATE
столбец:
CREATE TABLE t2 ( fname VARCHAR(50) NOT NULL, lname VARCHAR(50) NOT NULL, region_code TINYINT UNSIGNED NOT NULL, dob DATE NOT NULL)PARTITION BY RANGE( YEAR(dob) ) ( PARTITION d0 VALUES LESS THAN (1970), PARTITION d1 VALUES LESS THAN (1975), PARTITION d2 VALUES LESS THAN (1980), PARTITION d3 VALUES LESS THAN (1985), PARTITION d4 VALUES LESS THAN (1990), PARTITION d5 VALUES LESS THAN (2000), PARTITION d6 VALUES LESS THAN (2005), PARTITION d7 VALUES LESS THAN MAXVALUE);
Следующее использование операторов t2
может сделать из сокращения раздела
использования:
SELECT * FROM t2 WHERE dob = '1982-06-23';UPDATE t2 SET region_code = 8 WHERE dob BETWEEN '1991-02-15' AND '1997-04-25';DELETE FROM t2 WHERE dob >= '1984-06-21' AND dob <= '1999-06-21'
В случае последнего оператора оптимизатор может также действовать следующим образом:
Найдите раздел, содержащий нижний уровень диапазона.
YEAR('1984-06-21')
приводит к значению 1984
, который находится в разделе d3
.
Найдите раздел, содержащий верхний уровень диапазона.
YEAR('1999-06-21')
оценивает к 1999
,
который находится в разделе d5
.
Отсканируйте только эти два раздела и любые разделы, которые могут находиться между ними.
В этом случае это означает это только разделы d3
, d4
, и d5
сканируются. Остающиеся разделы
могут быть безопасно проигнорированы (и игнорируются).
Недопустимый DATE
и DATETIME
значения, на
которые ссылаются в WHERE
условие оператора против разделенной таблицы
обрабатывается как NULL
. Это означает что запрос такой как SELECT * FROM
не возвращает значений
(см. Ошибку #40972).partitioned_table
WHERE date_column
< '2008-12-00'
До сих пор мы только смотрели на использование в качестве примера RANGE
разделение,
но сокращение может быть применено с другими типами разделения также.
Рассмотрите таблицу, которая делится LIST
, где выражение разделения увеличивается
или уменьшается, такие как таблица t3
показанный здесь. (В этом примере мы
предполагаем ради краткости что region_code
столбец ограничивается значениями между
1 и 10 включительно.)
CREATE TABLE t3 ( fname VARCHAR(50) NOT NULL, lname VARCHAR(50) NOT NULL, region_code TINYINT UNSIGNED NOT NULL, dob DATE NOT NULL)PARTITION BY LIST(region_code) ( PARTITION r0 VALUES IN (1, 3), PARTITION r1 VALUES IN (2, 5, 8), PARTITION r2 VALUES IN (4, 9), PARTITION r3 VALUES IN (6, 7, 10));
Для оператора такой как SELECT * FROM t3 WHERE region_code BETWEEN 1 AND 3
,
оптимизатор определяет, в котором делит значения 1, 2, и 3 находятся (r0
и r1
) и пропускает остающиеся (r2
и r3
).
Для таблиц, которые делятся HASH
или KEY
, сокращение
раздела также возможно в случаях в который WHERE
пункт использует простое =
отношение против столбца используется в выражении разделения. Считайте таблицу
создаваемой как это:
CREATE TABLE t4 ( fname VARCHAR(50) NOT NULL, lname VARCHAR(50) NOT NULL, region_code TINYINT UNSIGNED NOT NULL, dob DATE NOT NULL)PARTITION BY KEY(region_code)PARTITIONS 8;
Может быть сокращен оператор, который сравнивает значение столбца с константой:
UPDATE t4 WHERE region_code = 7;
Сокращение может также использоваться для малых дальностей, потому что оптимизатор может повернуть такие условия
в IN
отношения. Например, используя ту же самую таблицу t4
столь же определенный ранее, запросы, такие как они могут быть сокращены:
SELECT * FROM t4 WHERE region_code > 2 AND region_code < 6;SELECT * FROM t4 WHERE region_code BETWEEN 3 AND 5;
В обоих этих случаях, WHERE
пункт преобразовывается оптимизатором в WHERE region_code IN (3, 4, 5)
.
Эта оптимизация используется, только если размер диапазона меньше чем число разделов. Рассмотрите этот оператор:
DELETE FROM t4 WHERE region_code BETWEEN 4 AND 12;
Диапазон в WHERE
пункт касается 9 значений (4, 5, 6, 7, 8, 9, 10, 11,
12), но t4
имеет только 8 разделов. Это означает что DELETE
не может быть сокращен.
Когда таблица делится HASH
или KEY
, сокращение может
использоваться только на целочисленных столбцах. Например, этот оператор не может использовать сокращение потому
что dob
a DATE
столбец:
SELECT * FROM t4 WHERE dob >= '2001-04-14' AND dob <= '2005-10-15';
Однако, если таблица хранит значения года в INT
столбец, затем наличие запроса WHERE year_col >=
2001 AND year_col <= 2005
может быть сокращен.
В MySQL 5.6.8 и позже, сокращение раздела отключается для всех таблиц, используя механизм хранения, который
обеспечивает автоматическое разделение, такой как NDB
механизм хранения,
используемый MySQL Cluster (не в настоящий момент поддерживаемый в MySQL 5.6). (Ошибка #14672885) Начинание с
MySQL 5.6.10, такие таблицы могут быть сокращены, если они явно делятся. (Ошибка #14827952)