Индексирование производительности ноль против фиктивных данных - PullRequest
1 голос
/ 28 октября 2009

У меня есть таблица со столбцами InTime и OutTime.

Обычно, когда я вставляю данные в эту таблицу, я устанавливаю InTime в DateTime, а OutTime в NULL. При удалении данных устанавливается значение OutTime.

Когда я получаю данные за определенное время, я использую что-то вроде:

where InTime < sometime and OutTime is > sometime or OutTime is null

Мой вопрос заключается в том, чтобы с точки зрения улучшения производительности запросов / индексов, я должен поместить какое-то значение в OutTime, например, max datetime, и сделать поле не обнуляемым?

Тогда мой запрос становится

where InTime < sometime and OutTime is > sometime

1 Ответ

2 голосов
/ 28 октября 2009

Оставьте поле NULL. Не используйте ИЛИ, используйте UNION ALL:

select ... from ... where InTime < sometime and OutTime is > sometime 
union all
select ... from ... where InTime < sometime and OutTime is null

Использование магических значений вместо NULL - путь к катастрофе. По крайней мере, он использует больше памяти. Более конкретно, он нарушает семантику NULL при применении ограничений базы данных, при вычислении агрегатов и в приложениях.

Использование OR в запросах вызывает проблемы с производительностью. Optmizer, скорее всего, превратит любой поиск диапазона индекса в сканы. Использование UNION обычно лучше, так как оптимизатор создаст два плана, один оптимальный для NULL, один опимальный для ненулевого, и объединит их.

Если у вас нет индекса для Intime и / или OutTime, тогда запрос все равно будет сканировать, и UNION будет работать хуже, чем OR, но тогда это не тот сценарий, о котором стоит говорить. Вопрос, конечно, в том, как оптимизировать запрос на правильно спроектированном хранилище.

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