Частичное использование многопольного индекса в MySQL - PullRequest
1 голос
/ 09 августа 2011

У меня есть таблица MyISAM с почти 1 миллиардом записей, скажем, с тремя полями: a, b и c.

Таблица имеет многополевой индекс btree для столбцов a, b и c в этомпорядок.Анализ индекса показывает, что количество полей для полей в этом индексе:

a: 112 (int)

b: 2694 (int)

c: 936426795 (datetime)

Это означает, что существует около 100 различных значений для a, около 20 различных значений для b, а для каждой комбинации a и b - множество значений c.

Iхотите выполнить запрос по определенному значению a и диапазону c.Что-то вроде

select a, b, c from mytable where a=4 and c >= "2011-01-01 00:00:00" and c < "2011-01-02 00:00:00"

Получение объяснения запроса показывает мне, что он действительно будет использовать индекс, но я не знаю, будет ли он использовать только первое поле индекса, а затем будет сканировать оставшуюся частьтаблицы, или если он будет достаточно умен, чтобы применить третий индекс поля, для каждого значения b, которое будет таким же, как выполнение 20 различных запросов, по одному для каждого различного значения b.

Любой, кто знаетвнутренняя работа индексов mysql может ответить на этот вопрос?

Редактировать: Я не спрашиваю, могу ли я иметь mysql для использования индекса только над a и c.Я знаю, как работают деревья, и я знаю, что вы можете использовать его только над a, a и b, или a и b и c.Я хотел бы знать, достаточно ли умен оптимизатор mysql, чтобы применить индекс ко всем значениям в b, чтобы он мог использовать индекс a + b + c, учитывая, что мощность b очень мала.

Рассмотрим еще более простой пример.Таблица с двумя столбцами: a и b, и индекс имеет количество элементов 1 больше a и 10000000 больше b.Mysql должен быть достаточно умен, чтобы знать, что есть только одно значение a, поэтому этот индекс эквивалентен индексу только по b, и должен использовать этот индекс при выполнении запросов только по b.

Ответы [ 3 ]

1 голос
/ 09 августа 2011

Справочное руководство по MySQL :: Как MySQL использует индексы

Если таблица имеет индекс из нескольких столбцов, любой крайний левый префикс index может использоваться оптимизатором для поиска строк. Например, если вы иметь индекс из трех столбцов (col1, col2, col3), вы проиндексировали возможности поиска по (col1), (col1, col2) и (col1, col2, col3). MySQL не может использовать индекс, если столбцы не образуют крайний левый префикс индекса.

a, c не является крайним левым префиксом индекса a, b, c, поэтому индекс нельзя использовать для разрешения поиска по c.

0 голосов
/ 19 февраля 2014

Ниже приведены некоторые факты, связанные с использованием индекса B-TREE mysql, и один пример, чтобы понять эту логику.

a) Если в какой-либо таблице содержится ок.75% тех же данных, тогда индекс не будет использоваться, вместо этого mysql будет выполнять сканирование таблицы.

b) Обычно mysql использует только один индекс на таблицу.

c) Методика упорядочения индекса: Mysql будет использовать индекссогласно их порядку.

Например, есть комбинированный индекс для полей a, b и c idx_a_b_c (a, b, c)

i.выберите a, b, c из mytable, где a = 4

Этот запрос будет использовать индекс, поскольку столбец 'a' находится первым в порядке индекса.

ii.выберите a, b, c из mytable, где a = 4 и b = 5

. В этом запросе будет использоваться комбинированный индекс для a & b, так как эти столбцы продолжаются в порядке индекса.выберите a, b, c из mytable, где a = 4 и b = 5 и c> = "2011-01-01 00:00:00"

В этом запросе будет использоваться комбинированный индекс для a, b & cпоскольку эти столбцы продолжаются в порядке индекса.

iv.выберите a, b, c из mytable, где c> = "2011-01-01 00:00:00"

Этот запрос не будет использовать индекс, так как mysql рассматривает индекс из самого левого угла, а столбец c не являетсяСамый левый столбец в индексе.

v.выберите a, b, c из mytable, где a = 4 и c> = "2011-01-01 00:00:00" и c <"2011-01-02 00:00:00" </p>

ThisВ запросе будет использоваться только индекс для столбца «a», но не для столбца «c», так как непрерывность нарушается здесь с левой стороны.Таким образом, этот запрос будет использовать индекс для столбца, а затем сканировать таблицу на наличие столбца c для соответствующих строк в соответствии с фильтром для столбца a.

0 голосов
/ 25 мая 2012

Этот вопрос имеет смысл с точки зрения того, что некоторые движки баз данных достаточно умны, чтобы сканировать индекс, а не сканировать таблицу.(И они позволяют хранить «данные» в индексе именно по этой причине.) Сканирование индекса будет быстрее, чем присоединение индекса к базовым данным, а затем ограничение (исключение) возвращаемых строк на основе предложения where.

Имеет смысл объединить только те строки в индексе, которые удовлетворяют условию where (для столбцов в индексе).Особенно, если вы используете большой кеш ключа ...

Может показаться, что этого не происходит в MySQL, что разочаровывает.Поэтому нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...