Индексирование нулей для быстрого поиска в DB2 - PullRequest
4 голосов
/ 22 сентября 2008

Насколько я понимаю, нули не индексируются в DB2, поэтому предположим, что у нас есть огромная таблица (Sales) со столбцом даты (sold_on), который обычно является датой, но иногда (10% времени) является нулевым. 1001 *

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

Мы можем быстро выполнить следующий запрос, поместив индекс в столбцы sold_on и total

Select * from Sales 
where 
Sales.sold_on between date1 and date2
and Sales.total = 9.99

Но индекс не сделает этот запрос быстрее:

Select * from Sales 
where 
Sales.sold_on is null
and Sales.total = 9.99

Поскольку индексация выполняется для значения.

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

Ответы [ 4 ]

5 голосов
/ 02 января 2009

Откуда у вас сложилось впечатление, что DB2 не индексирует NULL? Я не могу найти ничего в документации или статьях, подтверждающих претензию. И я только что выполнил запрос в большой таблице, используя ограничение IS NULL, включающее индексированный столбец, содержащий небольшую долю NULL; в этом случае DB2, безусловно, использовала индекс (проверенный EXPLAIN и наблюдая, что база данных реагировала мгновенно, вместо того, чтобы тратить время на сканирование таблицы).

Итак: я утверждаю, что у DB2 нет проблем с NULL в индексах не первичного ключа.

Но, как писали другие: ваши данные могут быть составлены таким образом, что DB2 считает, что использование индекса не будет быстрым. Или статистика базы данных не соответствует текущим таблицам.

4 голосов
/ 22 сентября 2008

Я не эксперт DB2, но если 10% ваших значений равны нулю, я не думаю, что индекс только по этому столбцу поможет вашему запросу. 10% - это слишком много, чтобы беспокоиться об использовании индекса - он просто сделает сканирование таблицы. Если бы вы говорили о 2-3%, я думаю, что он действительно использовал бы ваш индекс.

Подумайте о том, сколько записей на странице / блоке - скажем, 20. Причина использования индекса состоит в том, чтобы избежать выборки ненужных вам страниц. Вероятность того, что на данной странице будет 0 записей с нулевым значением, равна (90%) ^ 20 или 12%. Это не очень хорошая возможность - вам все равно понадобится 88% ваших страниц, так как использование индекса не очень полезно.

Если, однако, ваше предложение select включает только несколько столбцов (а не *) - скажем, просто salesid, вы, вероятно, можете заставить его использовать индекс для (sold_on, salesid), поскольку чтение страницы данных не не нужно - все данные будут в индексе.

1 голос
/ 22 сентября 2008

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

Если DB2 не будет индексировать нули, я бы предложил добавить логическое поле IsSold и установить его в значение true, когда будет установлена ​​дата sold_on (это можно сделать в триггере).

Это не самое лучшее решение, но оно может быть тем, что вам нужно.

0 голосов
/ 17 июня 2009

Троел верен; четные строки со значением SOLD_ON NULL получат выгоду от индекса по этому столбцу. Если вы выполняете поиск в диапазоне по SOLD_ON, вы можете получить еще большую выгоду, создав кластеризованный индекс, который начинается с SOLD_ON. В этом конкретном примере может не потребоваться много дополнительных издержек для поддержания порядка кластеризации на основе SOLD_ON, поскольку более новые добавленные строки, скорее всего, будут иметь более новую дату SOLD_ON.

...