Индексирование нулей для быстрого поиска в DB2

Насколько я понимаю, значения 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

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

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

В идеале я бы хотел, чтобы база данных вела себя, если бы нули были 0, и игнорировала их все за один шаг дерева поиска. Похоже, этого не происходит.

Dave 22.09.2008 20:33
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
4
1
4 043
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

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

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

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

Извините, я пытался сделать вопрос как можно более простым (фактический запрос, который у нас есть, состоит из миллиарда строк).

Dave 22.09.2008 20:32

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

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

Это не самое лучшее решение, но, возможно, оно вам понадобится.

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

Dave 22.09.2008 21:11

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

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

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

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

Другие вопросы по теме