Целочисленное представление даты - PullRequest
4 голосов
/ 29 октября 2008

В последнем проекте у нас была проблема с производительностью нескольких запросов, которые сильно зависели от упорядочения результатов по полю даты и времени (база данных MSSQL 2008).

Когда мы выполняли запросы с помощью ORDER BY RecordDate DESC (или ASC), запросы выполнялись в 10 раз медленнее, чем без этого. Упорядочение по любому другому полю не дало таких медленных результатов.

Мы перепробовали все параметры индексации, использовали мастер настройки, ничего не изменилось.

Одним из предложенных решений было преобразование поля даты и времени в целочисленное поле, представляющее количество секунд или миллисекунд в этом поле даты и времени. Он будет рассчитан по простому алгоритму, что-то вроде «получите мне количество секунд от RecordDate до 1980-01-01». Это значение будет сохранено при вставке, и вся сортировка будет выполняться в целочисленном поле, а не в поле даты и времени.

Мы никогда не пробовали, но мне интересно, что вы, ребята, думаете?

Ответы [ 13 ]

3 голосов
/ 29 октября 2008

Я всегда храню даты в виде целых чисел, используя стандартизированную unix timestamp , так как большинство языков, которые я программирую, используют это как представление даты и времени по умолчанию. Очевидно, что это делает сортировку по дате намного более эффективной.

Так что да, я рекомендую:)

2 голосов
/ 29 октября 2008

Я думаю, что в основном именно так SQL-тип даты и времени хранится за кулисами в SQL Server, поэтому я был бы удивлен этими результатами.

Можете ли вы повторить медлительность в Northwinds или Pubs - если это так, возможно, стоит позвонить MS, поскольку она не должна быть в 10 раз медленнее. Если нет, то, возможно, что-то странное в вашем столе.

Если вы используете SQL 2008 и вам нужно хранить только даты (не часть времени), вы можете попробовать использовать новый тип данных date. Это имеет меньшую точность и поэтому должно быть быстрее сортировать.

1 голос
/ 29 октября 2008

Вам действительно нужен DateTime или, более конкретно, часть 'time'? Если нет, я бы исследовал сохранение даты в виде целочисленного или строкового представления формата даты ISO (ГГГГММДД) и посмотрел, дает ли это необходимое повышение производительности. Хранение значений ticks / time_t и т. Д. Даст вам возможность также хранить время, но я бы не стал беспокоиться об этом, если вам действительно не нужен компонент time. Кроме того, дополнительная ценность хранения понятной для человека даты заключается в том, что отладку проблем, связанных с данными, несколько проще просто потому, что вы можете читать и понимать данные, с которыми работает ваша программа.

1 голос
/ 29 октября 2008

Разве даты не хранятся как числа уже?

1 голос
/ 29 октября 2008

Вставки из .Net Code ...

Вы можете сохранить значение DateTime.Ticks в столбце bigint в БД и индексировать по нему.

С точки зрения обновления вашей существующей базы данных, было бы относительно тривиально написать функцию CLR для преобразования существующих DateTimes в TickCount в соответствии с

ALTER TABLE dbo.MyTable ADD TickCount BigInt Null

Update dbo.MyTable Set TickCount = CLRFunction(DateTimeColumn)

Это определенно выполнимо и значительно улучшит вашу способность сортировки

0 голосов
/ 27 января 2011
SELECT CAST(REPLACE(convert(varchar, GETDATE(), 102),'.','')AS INT) 

- работает довольно хорошо (и быстро!).

0 голосов
/ 11 ноября 2008

Я бы посоветовал вам использовать юлианскую дату, как в Excel ( текст ссылки ). Все финансовые приложения используют это представление для повышения производительности, и оно обеспечивает относительно хороший диапазон значений.

0 голосов
/ 30 октября 2008

Я видел базу данных BI, где даты хранятся в виде целого числа в формате ГГГММДД. Отдельная таблица используется для соотнесения этих целых чисел с эквивалентными датой-временем, форматированной строкой, номером года, номером квартала, номером месяца, днем ​​недели, статусом праздника и т. Д. Все, что вам нужно сделать, - это присоединиться к этой таблице, чтобы получить что-либо связанное с датой. что тебе нужно. Очень удобно.

0 голосов
/ 30 октября 2008

Является ли ваша RecordDate одним из полей в предложении WHERE? Кроме того, является ли RecordDate вашим единственным критерием ORDER BY? В-третьих, является ли ваш запрос многостольным соединением или запросом к одной таблице? Если вы не ВЫБИРАЕТЕ на RecordDate и используете его в качестве критерия ORDER BY, это может быть причиной проблемы с производительностью, так как в этом случае индексы не будут способствовать сортировке. Индексы будут пытаться решить проблемы объединения, а затем будет происходить сортировка.

Если это так, то изменение типа данных вашей RecordDate может вам не сильно помочь, поскольку вы по-прежнему применяете сортировку для набора записей после факта.

0 голосов
/ 30 октября 2008

Я голосую за индексацию. Как я уже говорил в комментариях выше, ваши даты в любом случае хранятся в виде двух int за кулисами (sql 2000 в любом случае). Я не вижу, чтобы это имело значение. Трудно сказать, в чем заключается настоящая проблема без дополнительной информации, но мое внутреннее чувство заключается в том, что это не проблема. Если у вас есть dev environemnt (и вы должны :)), попробуйте создать там поле int и выполнить необработанные запросы. Это не должно быть трудно сделать, и вы получите окончательные результаты по этой идее.

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