Насколько я понимаю, значения NULL в DB2 не индексируются, поэтому при условии, что у нас есть огромная таблица (Продажи) со столбцом даты (sold_on), который обычно является датой, но иногда (10% времени) равен нулю.
Кроме того, давайте предположим, что это устаревшее приложение, которое мы не можем изменить, поэтому эти нули остаются там и что-то значат (скажем, продажи, которые были возвращены).
Мы можем быстро выполнить следующий запрос, поместив индекс в столбцы 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
Поскольку индексация выполняется по значению.
Могу ли я проиндексировать нули? Может, поменяв тип индекса? Индексируете столбец индикатора?


Я не эксперт по DB2, но если 10% ваших значений равны нулю, я не думаю, что индекс только для этого столбца когда-либо поможет вашему запросу. 10% - это слишком много, чтобы использовать индекс - это просто сканирование таблицы. Если бы вы говорили о 2-3%, я думаю, что на самом деле использовался бы ваш индекс.
Подумайте, сколько записей находится на странице / блоке - скажем, 20. Причина использования индекса - избежать загрузки ненужных страниц. Вероятность того, что данная страница будет содержать 0 пустых записей, равна (90%) ^ 20 или 12%. Это не очень хорошие шансы - вам в любом случае понадобится 88% ваших страниц, использование индекса не очень полезно.
Если, однако, ваше предложение select включало только несколько столбцов (а не *) - скажем, просто salesid, вы, вероятно, могли бы заставить его использовать индекс для (sold_on, salesid), так как чтение страницы данных не будет необходимо - все данные будут в индексе.
Извините, я пытался сделать вопрос как можно более простым (фактический запрос, который у нас есть, состоит из миллиарда строк).
Эмпирическое правило состоит в том, что индекс полезен для значений до 15% записей. ... так что здесь может быть полезен индекс.
Если DB2 не будет индексировать значения NULL, я бы предложил добавить логическое поле IsSold и установить для него значение true всякий раз, когда устанавливается дата sold_on (это можно сделать в триггере).
Это не самое лучшее решение, но, возможно, оно вам понадобится.
Ага, это одно из наших потенциальных решений. Но действительно кажется, что я должен просто иметь возможность где-нибудь щелкнуть переключателем, а нам еще не нужен триггер.
Откуда у вас создалось впечатление, что DB2 не индексирует NULL? Я не могу найти ничего в документации или статьях, подтверждающих претензию. И я только что выполнил запрос в большой таблице, используя ограничение IS NULL, включая индексированный столбец, содержащий небольшую часть NULL; в этом случае DB2 определенно использовала индекс (проверенный с помощью EXPLAIN и наблюдение, что база данных ответила мгновенно, вместо того, чтобы тратить время на сканирование таблицы).
Итак: я утверждаю, что у DB2 нет проблем с NULL в индексах, не являющихся первичными ключами.
Но, как писали другие: ваши данные могут быть составлены таким образом, что DB2 считает, что использование индекса не будет быстрее. Или статистика базы данных не актуальна для задействованных таблиц.
Троэлс прав; даже строки со значением SOLD_ON, равным NULL, выиграют от индексации этого столбца. Если вы выполняете ранжированный поиск на SOLD_ON, вы можете получить еще больше, создав кластеризованный индекс, который начинается с SOLD_ON. В этом конкретном примере может не потребоваться много дополнительных накладных расходов для поддержания порядка кластеризации на основе SOLD_ON, поскольку добавленные новые строки, скорее всего, будут иметь более новую дату SOLD_ON.
В идеале я бы хотел, чтобы база данных вела себя, если бы нули были 0, и игнорировала их все за один шаг дерева поиска. Похоже, этого не происходит.