57
СУБД Лекция 7 Павел Щербинин

СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Embed Size (px)

Citation preview

Page 1: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

СУБД

Лекция 7

Павел Щербинин

Page 2: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Оптимизируйте доступ к

данным

• не извлекает ли приложение больше данных, чем нужно

• не анализирует ли сервер MySQL больше строк, чем это необходимо

Типичные ошибки:• Выборка ненужных строк• Выборка всех столбцов из соединения нескольких

таблиц• Выборка всех столбцов

Page 3: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Декомпозиция соединения

SELECT *

FROM tag

JOIN tag_post ON tag_post.tag_id=tag.id

JOIN post ON tag_post.post_id=post.id

WHERE tag.tag=mysql;

SELECT * FROM tag WHERE tag=mysql;

SELECT * FROM tag_post WHERE tag_id=1234;

SELECT * FROM post WHERE post.id in

(123,456,567,9098,8904);

Page 4: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Декомпозиция соединения

Соединение в приложении может оказаться эффективнее в следующих случаях:

• Организован кэш и вы повторно используете ранее запрошенные данные

• Часто используются таблицы типа MyISAM• Данные распределены по нескольким серверам• Вместо соединения с большой таблицей используется

список IN()• В соединении несколько раз встречается одна и та же

таблица

Page 5: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Выполнение запросов

Page 6: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Состояние запроса

SHOW FULL PROCESSLIST;

SleepПоток ожидает поступления нового запроса от клиента.

QueryПоток либо занят выполнением запроса, либо отправляет клиенту результаты.

LockedПоток ожидает предоставления табличной блокировки на уровне сервера.

Analyzing и StatisticsПоток проверяет статистику, собранную подсистемой хранения, и

оптимизирует запрос.Copying to tmp table [on disk]

Поток обрабатывает запрос и копирует результаты во временную таблицу.Sorting result

Поток занят сортировкой результирующего набора.Sending data

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

Page 7: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Оптимизатор запросов

SELECT SQL_NO_CACHE COUNT(*) FROM sakila.film_actor;

mysql> SHOW STATUS LIKE last_query_cost;

COUNT(*)

5462

Variable_name Value

Last_query_cost 1040.599000

Page 8: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Оптимизатор запросов

• Некорректная статистика. • Принятая метрика стоимости не всегда эквивалентна истинной

стоимости выполнения запроса.• Представление MySQL о том, что такое «оптимально», может

расходиться с вашим представлением. • MySQL не берет в расчет другие одновременно выполняющиеся

запросы.• MySQL не всегда выполняет оптимизацию по стоимости. Иногда он

просто следует правилам.• Оптимизатор не учитывает стоимость операций, которые ему

неподконтрольны, например выполнение хранимых или определенных пользователем функций.

• Не всегда оптимизатор способен рассмотреть все возможные планы выполнения, поэтому оптимальный план он может просто не увидеть.

Page 9: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Оптимизатор запросов

Изменение порядка соединенияТаблицы не обязательно соединять именно в том порядке, который указан в

запросе.Применение алгебраических правил эквивалентности

MySQL применяет алгебраические преобразования для упрощениявыражений и приведения их к каноническому виду. Она умеет так-же вычислятьконстантные выражения, исключая заведомо невыполнимые и всегдавыполняющиеся условия. (5=5 AND a>5) -> a>5(a < b AND b=c) AND a=5 -> b>5 AND b=c AND a=5Оптимизации COUNT(), MIN() и MAX()

Наличие индексов и сведений о возможности хранения NULL-значений встолбцах часто позволяет вообще не вычислять эти выражения. Если примененатакая оптимизация, то в плане, выведенном командой EXPLAIN, будетприсутствовать фраза «Select tables optimized away» (некоторые таблицыисключены при оптимизации).

Page 10: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Оптимизатор запросов

Вычисление и свертка константных выраженийЕсли MySQL обнаруживает, что выражение можно свернуть в константу, то

делает это на стадии оптимизации.

EXPLAIN SELECT film.film_id, film_actor.actor_id

FROM sakila.film

INNER JOIN sakila.film_actor USING(film_id)

WHERE film.film_id = 1;

| id | select_type | table | type | key | ref | rows || 1 | SIMPLE | film | const | PRIMARY | const | 1 || 1 | SIMPLE | film_actor | ref | idx_fk_film_id | const | 10 |Покрывающие индексы

Если индекс содержит все необходимые запросу столбцы, то MySQL можетвоспользоваться им, вообще не читая данные таблицы.Оптимизация подзапросов

MySQL умеет преобразовывать некоторые виды подзапросов в болееэффективные эквивалентные формы, сводя их к поиску по индексу.

Page 11: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Оптимизатор запросов

Раннее завершениеMySQL может прекратить обработку запроса (или какой-то шаг обработки), как только поймет, что этот запрос или шаг полностью выполнен.

EXPLAIN SELECT film.film_id FROM sakila.film WHERE film_id = -1;

| id |...| Extra |

| 1 |...| Impossible WHERE noticed after reading const tables |

Сравнение по списку IN( )Во многих СУБД оператор IN() – не более чем синоним нескольких условий OR, поскольку логически они эквивалентны. Но не в MySQL, здесь перечисленные в списке IN()значения сортируются, и для работы с ним применяется быстрыйдвоичный поиск.

Page 12: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Оптимизатор запросов

Распространение равенстваMySQL распознает ситуации, когда в некотором запросе два столбца должны быть равны, – например, в условии JOIN, и распространяет условие WHERE на эквивалентные столбцы.

SELECT film.film_id

FROM sakila.film

INNER JOIN sakila.film_actor USING(film_id)

WHERE film.film_id > 500;

... WHERE film.film_id > 500 AND film_actor.film_id > 500

Page 13: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Соединения (JOIN) в MySQL

SELECT tbl1.col1, tbl2.col2FROM tbl1 INNER JOIN tbl2 USING(col3)WHERE tbl1.col1 IN(5,6);outer_iter = iterator over tbl1 where col1 IN(5,6)outer_row = outer_iter.nextwhile outer_row

inner_iter = iterator over tbl2 where col3 = outer_row.col3inner_row = inner_iter.nextwhile inner_row

output [ outer_row.col1, inner_row.col2 ]inner_row = inner_iter.next

endouter_row = outer_iter.next

end

Page 14: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Соединения (JOIN) в MySQL

SELECT tbl1.col1, tbl2.col2 FROM tbl1

LEFT OUTER JOIN tbl2 USING(col3) WHERE tbl1.col1 IN(5,6);

outer_iter = iterator over tbl1 where col1 IN(5,6)

outer_row = outer_iter.next

while outer_rowinner_iter = iterator over tbl2 where col3 = outer_row.col3inner_row = inner_iter.nextif inner_row

while inner_rowoutput [ outer_row.col1, inner_row.col2 ]inner_row = inner_iter.next

endelse

output [ outer_row.col1, NULL ]endouter_row = outer_iter.next

end

Page 15: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Соединения (JOIN) в MySQL

Page 16: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

План выполнения

Page 17: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Оптимизатор сортировки

• Двухпроходный (старый)Читает указатели на строки и столбцы, упомянутые во фразе ORDER BY, сортирует их, затем проходит по отсортированному списку и снова читает исходные строки, чтобы вывести результат.

• Однопроходный (новый)Читает все необходимые запросу столбцы, сортирует строки по столбцам, упомянутым во фразе ORDER BY, проходит по отсортированному списку и выводит заданные столбцы. Следовательно, в буфер сортировки поместится меньше строк и надо будет выполнить больше циклов слияния.

Page 18: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Коррелированные подзапросы

SELECT * FROM sakila.film

WHERE film_id IN(

SELECT film_id FROM sakila.film_actor WHERE actor_id = 1);

Page 19: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Коррелированные подзапросы

SELECT * FROM sakila.film

WHERE film_id IN(

SELECT film_id FROM sakila.film_actor WHERE actor_id = 1);

SELECT GROUP_CONCAT(film_id)

FROM sakila.film_actor

WHERE actor_id = 1;

-- Result:

1,23,25,106,140,166,277,361,438,499,506,509,605,635,749

,832,939,970,980

SELECT * FROM sakila.film

WHERE film_id

IN(1,23,25,106,140,166,277,361,438,499,506,509,605,635,

749,832,939,970,980);

Page 20: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Коррелированные подзапросы

SELECT * FROM sakila.film

WHERE film_id IN(

SELECT film_id FROM sakila.film_actor WHERE actor_id = 1);

SELECT * FROM sakila.film

WHERE EXISTS (

SELECT * FROM sakila.film_actor WHERE actor_id = 1

AND film_actor.film_id = film.film_id);

Page 21: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Слияние индексов

SELECT film_id, actor_id FROM sakila.film_actor

WHERE actor_id = 1 OR film_id = 1;

Page 22: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Слияние индексов

SELECT film_id, actor_id FROM sakila.film_actor

WHERE actor_id = 1 OR film_id = 1;

SELECT film_id, actor_id FROM sakila.film_actor

WHERE actor_id = 1

UNION ALL

SELECT film_id, actor_id FROM sakila.film_actor

WHERE film_id = 1 AND actor_id <> 1;

Page 23: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Непоследовательный просмотр

индексов

SELECT ... FROM tbl WHERE b BETWEEN 2 AND 3;

Page 24: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Непоследовательный просмотр

индексов

SELECT ... FROM tbl WHERE b BETWEEN 2 AND 3;

Page 25: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Непоследовательный просмотр

индексов

EXPLAIN SELECT actor_id, MAX(film_id)

FROM sakila.film_actor

GROUP BY actor_id\G

********************* 1. row **************************id: 1select_type: SIMPLEtable: film_actortype: rangepossible_keys: NULLkey: PRIMARYkey_len: 2Ограничения оптимизатора MySQL 241ref: NULLrows: 396Extra: Using index for group-by

Page 26: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Непоследовательный просмотр

индексов

SELECT MIN(actor_id) FROM sakila.actor

WHERE first_name = PENELOPE;

Page 27: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Непоследовательный просмотр

индексов

SELECT MIN(actor_id) FROM sakila.actor

WHERE first_name = PENELOPE;

SELECT actor_id FROM sakila.actor USE INDEX(PRIMARY)

WHERE first_name = PENELOPE LIMIT 1;

Page 28: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

SELECT & UPDATE

UPDATE tbl AS outer_tbl

SET cnt = (

SELECT count(*) FROM tbl AS inner_tbl

WHERE inner_tbl.type = outer_tbl.type

);

Page 29: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

SELECT & UPDATE

UPDATE tbl AS outer_tbl

SET cnt = (

SELECT count(*) FROM tbl AS inner_tbl

WHERE inner_tbl.type = outer_tbl.type

);

ERROR 1093 (HY000): You can’t specify target table‘outer_tbl’ for update in FROM clause

Page 30: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

SELECT & UPDATE

UPDATE tbl AS outer_tbl

SET cnt = (

SELECT count(*) FROM tbl AS inner_tbl

WHERE inner_tbl.type = outer_tbl.type

);

ERROR 1093 (HY000): You can’t specify target table‘outer_tbl’ for update in FROM clause

UPDATE tbl

INNER JOIN(

SELECT type, count(*) AS cnt

FROM tbl

GROUP BY type

) AS der USING(type)

SET tbl.cnt = der.cnt;

Page 31: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Что делает COUNT()

COUNT() – это особая функция, которая решает две оченьразные задачи: подсчитывает значения и строки.

Значение – это выражение, отличное от NULL.

COUNT(*) просто подсчитывает количество строк в результирующем наборе.

Если вы хотите знать, сколько строк в результирующем наборе, всегда употребляйте COUNT(*).

МИФЫ:Для таблиц типа MyISAM запросы, содержащие функцию COUNT(), выполняются очень быстро.

Page 32: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Оптимизация COUNT()

SELECT COUNT(*) FROM world.City WHERE ID > 5;

Page 33: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Оптимизация COUNT()

SELECT COUNT(*) FROM world.City WHERE ID > 5;

SELECT (SELECT COUNT(*) FROM world.City) - COUNT(*)

FROM world.City WHERE ID <= 5;

Page 34: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Оптимизация COUNT()

SELECT COUNT(*) FROM world.City WHERE ID > 5;

SELECT (SELECT COUNT(*) FROM world.City) - COUNT(*)

FROM world.City WHERE ID <= 5;

SELECT COUNT(color= blue OR color= red) FROM items;

SELECT COUNT(*) FROM items

WHERE color= blue AND color= red;

Page 35: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Оптимизация COUNT()

SELECT COUNT(*) FROM world.City WHERE ID > 5;

SELECT (SELECT COUNT(*) FROM world.City) - COUNT(*)

FROM world.City WHERE ID <= 5;

SELECT COUNT(color= blue OR color= red) FROM items;

SELECT COUNT(*) FROM items

WHERE color= blue AND color= red;

SELECT SUM(IF(color = blue, 1, 0)) AS blue,

SUM(IF(color = red, 1, 0)) -> AS red FROM items;

Page 36: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Оптимизация COUNT()

SELECT COUNT(*) FROM world.City WHERE ID > 5;

SELECT (SELECT COUNT(*) FROM world.City) - COUNT(*)

FROM world.City WHERE ID <= 5;

SELECT COUNT(color= blue OR color= red) FROM items;

SELECT COUNT(*) FROM items

WHERE color= blue AND color= red;

SELECT SUM(IF(color = blue, 1, 0)) AS blue,

SUM(IF(color = red, 1, 0)) AS red FROM items;

SELECT COUNT(color = blue OR NULL) AS blue, COUNT(color

= red OR NULL) AS red FROM items;

Page 37: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Оптимизация запросов с JOIN

• Стройте индексы по столбцам, используемым во фразах ON или USING.

• При добавлении индексов учитывайте порядок соединения. В общем случае следует индексировать только вторую таблицу в порядке соединения, если, конечно, индекс не нужен для каких-то других целей.

• Старайтесь, чтобы в выражениях GROUP BY и ORDER BY встречались столбцы только из одной таблицы, тогда у MySQLпоявится возможность воспользоваться для этой операции индексом.

• Будьте внимательны при переходе на новую версию MySQL, поскольку в разные моменты изменялись синтаксис соединения, приоритеты операторов и другие аспекты поведения.

Page 38: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Оптимизация GROUP BY и

DISTINCT

SELECT actor.first_name, actor.last_name, COUNT(*)

FROM sakila.film_actor

INNER JOIN sakila.actor USING(actor_id)

GROUP BY actor.first_name, actor.last_name;

Page 39: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Оптимизация GROUP BY и

DISTINCT

SELECT actor.first_name, actor.last_name, COUNT(*)

FROM sakila.film_actor

INNER JOIN sakila.actor USING(actor_id)

GROUP BY actor.first_name, actor.last_name;

SELECT actor.first_name, actor.last_name, COUNT(*)

FROM sakila.film_actor

INNER JOIN sakila.actor USING(actor_id)

GROUP BY film_actor.actor_id;

Page 40: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Оптимизация GROUP BY и

DISTINCT

SELECT actor.first_name, actor.last_name, COUNT(*)

FROM sakila.film_actor

INNER JOIN sakila.actor USING(actor_id)

GROUP BY actor.first_name, actor.last_name;

SELECT MIN(actor.first_name), MAX(actor.last_name),

COUNT(*)

FROM sakila.film_actor

INNER JOIN sakila.actor USING(actor_id)

GROUP BY film_actor.actor_id;

Page 41: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Оптимизация GROUP BY и

DISTINCT

SELECT actor.first_name, actor.last_name, COUNT(*)

FROM sakila.film_actor

INNER JOIN sakila.actor USING(actor_id)

GROUP BY actor.first_name, actor.last_name;

SELECT actor.first_name, actor.last_name, c.cnt

FROM sakila.actor

INNER JOIN (

SELECT actor_id, COUNT(*) AS cnt

FROM sakila.film_actor

GROUP BY actor_id

) AS c USING(actor_id) ;

Page 42: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Оптимизация LIMIT со

смещением

SELECT film_id, description

FROM sakila.film

ORDER BY title

LIMIT 50, 5;

Page 43: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Оптимизация LIMIT со

смещением

SELECT film_id, description

FROM sakila.film

ORDER BY title

LIMIT 50, 5;

SELECT film.film_id, film.description

FROM sakila.film

INNER JOIN (

SELECT film_id FROM sakila.film

ORDER BY title LIMIT 50, 5

) AS lim USING(film_id);

Page 44: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Оптимизация LIMIT со

смещением

SELECT film_id, description

FROM sakila.film

ORDER BY title

LIMIT 50, 5;

SELECT film.film_id, film.description

FROM sakila.film

INNER JOIN (

SELECT film_id FROM sakila.film

ORDER BY title LIMIT 50, 5

) AS lim USING(film_id);

SELECT film_id, description FROM sakila.film

WHERE position BETWEEN 50 AND 54 ORDER BY position;

Page 45: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

SQL_CALC_FOUND_ROWS

SELECT SQL_CALC_FOUND_ROWS film_id, description

FROM sakila.film

ORDER BY title

LIMIT 50, 5;

Page 46: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Кэш запросов

• Перед началом обработки запроса на чтение нужно проверить, есть ли он в кэше

• Если запрос допускает кэширование, но еще не помещен в кэш, то нужно потратить некоторое время на запись в кэш сгенерированных результатов

• Наконец, при обработке любого запроса на запись необходимо сделать недействительными все записи в кэше, в которых встречается измененная таблица

Page 47: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Кэш запросов

Page 48: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Кэш запросов

Page 49: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Объединенные таблицы и секционирование

Позволяют:• Отделить статические данные от изменяющихся

• Воспользоваться физической близостью взаимосвязанных данных для оптимизации запросов

• Проектировать таблицы так, чтобы запрос обращался к возможно меньшему объему данных

• Упростить обслуживание очень больших наборов данных (в этом вопросе объединенные таблицы обладают некоторыми преимуществами по сравнению с секционированными)

Page 50: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Объединенные таблицы

CREATE TABLE t1(a INT NOT NULL PRIMARY KEY)

ENGINE=MyISAM;

CREATE TABLE t2(a INT NOT NULL PRIMARY KEY)

ENGINE=MyISAM;

INSERT INTO t1(a) VALUES(1),(2);

INSERT INTO t2(a) VALUES(1),(2);

CREATE TABLE mrg(a INT NOT NULL PRIMARY KEY)

ENGINE=MERGE UNION=(t1, t2) INSERT_METHOD=LAST;

SELECT a FROM mrg;

| a |

| 1 || 1 || 2 || 2 |

Page 51: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Объединенные таблицы

• Для объединенной таблицы необходимо больше открытых файловых дескрипторов, чем для обычной таблицы, содержащей те же данные.

• Команда CREATE, которая создает объединенную таблицу, не проверяет, совместимы ли ее составляющие. Если определения объединяемых таблиц слегка различаются, то MySQL может создать объединенную таблицу, которой впоследствии не сумеет воспользоваться.

• Запросы, обращенные к объединенной таблице, переадресуются к каждой из составляющих таблиц. В результате поиск единственной строки может оказаться медленнее по сравнению с поиском в одной таблице.

• Сканирование выполняется для объединенной таблицы так же быстро, как для обычной

• Поиск по уникальному и первичному ключу прекращается, как только искомая строка найдена.

• Составляющие таблицы читаются в порядке, указанном в команде CREATE TABLE.

Page 52: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Секционирование

CREATE TABLE orders_range (

customer_surname VARCHAR(30),

store_id INT,

salesperson_id INT,

order_date DATE,

note VARCHAR(500)

) ENGINE = MYISAM

PARTITION BY RANGE( YEAR(order_date) ) (

PARTITION p_old VALUES LESS THAN(2008),

PARTITION p_2008 VALUES LESS THAN(2009),

PARTITION p_2009 VALUES LESS THAN(MAXVALUE)

);

Page 53: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Секционирование

RANGE

По диапазону значений

PARTITION BY RANGE (store_id) (

PARTITION p0 VALUES LESS THAN (10),

PARTITION p1 VALUES LESS THAN (20),

PARTITION p3 VALUES LESS THAN (30)

);

Page 54: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Секционирование

LIST

По точному списку значений

PARTITION BY LIST(store_id) (

PARTITION pNorth VALUES IN (3,5,6,9,17),

PARTITION pEast VALUES IN (1,2,10,11,19,20)

)

Page 55: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Секционирование

KEY

Почти то же самое что и HASH, но по ключу.

PARTITION BY KEY(s1)

PARTITIONS 10;

Page 56: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Секционирование

• Все секции должны управляться одной и той же подсистемой хранения. Например, нельзя сжать только часть секций, хотя для составляющих объединенной таблицы это допустимо.

• Любой уникальный индекс над секционированной таблицей должен содержать столбцы, на которые ссылается функция секционирования.

• Хотя сервер MySQL может обойтись без доступа к каждой секции при обработке запроса к секционированной таблице, он тем менее ставит блокировки на все секции.

• Существует ряд ограничений на функции и выражения, которые можно использовать в механизме секционирования.

• Некоторые подсистемы хранения вообще не поддерживают секционирование.

• Внешние ключи не работают.

Page 57: СУБД 2013 Лекция №7 "Оптимизация запросов и индексирование"

Спасибо за вниманиеПавел Щербинин

[email protected]