Spec-Zone .ru
спецификации, руководства, описания, API

18.4. Сокращение раздела

Этот раздел обсуждает оптимизацию, известную как сокращение раздела. Базовое понятие позади сокращения раздела относительно просто, и может быть описано, поскольку "Не сканируют разделы, где не может быть никаких совпадающих значений". Предположите, что у Вас есть разделенная таблица 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 условие может быть уменьшено до любого из следующих двух случаев:

В первом случае оптимизатор просто оценивает выражение разделения для данного значения, определяет, какой раздел содержит то значение, и сканирует только этот раздел. Во многих случаях знак "равно" может быть заменен другим арифметическим сравнением, включая <, >, <=, >=, и <>. Некоторое использование запросов 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'

В случае последнего оператора оптимизатор может также действовать следующим образом:

  1. Найдите раздел, содержащий нижний уровень диапазона.

    YEAR('1984-06-21') приводит к значению 1984, который находится в разделе d3.

  2. Найдите раздел, содержащий верхний уровень диапазона.

    YEAR('1999-06-21') оценивает к 1999, который находится в разделе d5.

  3. Отсканируйте только эти два раздела и любые разделы, которые могут находиться между ними.

    В этом случае это означает это только разделы d3, d4, и d5 сканируются. Остающиеся разделы могут быть безопасно проигнорированы (и игнорируются).

Важный

Недопустимый DATE и DATETIME значения, на которые ссылаются в WHERE условие оператора против разделенной таблицы обрабатывается как NULL. Это означает что запрос такой как SELECT * FROM partitioned_table WHERE date_column < '2008-12-00' не возвращает значений (см. Ошибку #40972).

До сих пор мы только смотрели на использование в качестве примера 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)