2013-07-06 3 views
0

Если я следующий в ИНЕКЕ:не использует индекс в котором пункт

(approps_precio * moneda_valor BETWEEN 2000 AND 6000) 

он не использует idx_approps_precio индекс.

Но

(approps_precio BETWEEN 2000 AND 6000) 

делает это очень хорошо.

Есть ли способ добавить * операцию и по-прежнему использовать индекс ?.

Заранее спасибо.

+0

Вы считаете, что вы храните продукт 'approps_precio * moneda_valor' в своем (n индексированном) столбце? Вы можете использовать [триггеры] (http://dev.mysql.com/doc/en/triggers.html), чтобы гарантировать, что его значение остается совместимым с базовыми столбцами. – eggyal

ответ

0

Операция * делает ваше значение 0 и, следовательно, вне зоны действия, когда moneda_valor равно null. Таким образом, вы можете записать его в виде:

approps_precio BETWEEN 2000 AND 6000 and moneda_valor IS NOT NULL

1

ли moneda_valor постоянная? Если нет, индекс на approps_precio бесполезен, если вы ищете значения approps_precio, умноженные на moneda_valor.

+0

не является константой, является значением, полученным предыдущим соединением. – KillDash9

1

Я копаться, чтобы найти официальную документацию для поддержки того, что Пол Дюбуа (хотя член документации команды MySQL) говорит, что в пятой главе «Оптимизация запросов» своей книги MySQL (Developer's Library):

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

Лучшее, что я могу найти раздел на Optimizer Transpositions в руководстве Internals:

Однако MySQL не поддерживает транспозиции, где арифметика существует. Таким образом:

WHERE 5 = -column1 

не обрабатывают так же, как:

WHERE column1 = -5 

Транспозиций для выражения столбца вида = константа являются идеальными для индекса поиска.

В этом случае можно воспользоваться индексом на approps_precio переписав критерии фильтрации путем деления через по moneda_valor:

WHERE approps_precio BETWEEN 2000/moneda_valor AND 6000/moneda_valor 

Обратите внимание, что MySQL будет по-прежнему необходимо оценить разделение для каждой записи , поэтому я не уверен, что многое будет спасено.

Смежные вопросы