У меня есть следующая таблица (сервер SQL Server 2016)
CREATE TABLE [dbo].[MyTable](
[RefID] [uniqueidentifier] NOT NULL,
[LG_ID] [bigint] NOT NULL,
[APP_SERVER_ID] [int] NOT NULL,
[WEB_SERVER_ID] [int] NOT NULL,
[WEB_BROWSER_ID] [int] NULL,
[CLIENT_TYPE_ID] [int] NOT NULL,
[OS_NAME_ID] [int] NULL,
[CLIENT_VERSION] [varchar](10) NULL,
[OS_VERSION] [varchar](10) NULL,
[BROWSER_VERSION] [varchar](10) NULL,
[DETAILS] [nvarchar](255) NULL,
[LG_SOURCE_TABLE] [char](2) NOT NULL,
[LG_TIME] [datetime] NULL,
CONSTRAINT [PK_MyTable] PRIMARY KEY CLUSTERED
(
[RefID] ASC,
[LG_ID] ASC,
[LG_SOURCE_TABLE] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [Primary]
) ON [Primary]
CREATE NONCLUSTERED INDEX [IX_MyTable_LG_TIME] ON [dbo].[MyTable]
(
[LG_TIME] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
ALTER TABLE [dbo].[MyTable] ADD CONSTRAINT [PK_MyTable] PRIMARY KEY CLUSTERED
(
[RefID] ASC,
[LG_ID] ASC,
[LG_SOURCE_TABLE] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
И я запрашиваю данные следующими методами (я использую только метод 1, другие тесты, которые я делаю):
METHOD 1:
SELECT
[RefID],
[LG_ID],
[APP_SERVER_ID],
[WEB_SERVER_ID],
[WEB_BROWSER_ID],
[CLIENT_TYPE_ID],
[OS_NAME_ID],
[CLIENT_VERSION],
[OS_VERSION],
[BROWSER_VERSION],
[DETAILS],
[LG_SOURCE_TABLE],
[LG_TIME]
FROM
[MyTable] WITH (NOLOCK)
WHERE
[LG_TIME] >= '20190923'
AND [LG_TIME] < '20190924'
--returns 19.880.317 rows
METHOD 2:
SELECT
[RefID],
[LG_ID],
[APP_SERVER_ID],
[WEB_SERVER_ID],
[WEB_BROWSER_ID],
[CLIENT_TYPE_ID],
[OS_NAME_ID],
[CLIENT_VERSION],
[OS_VERSION],
[BROWSER_VERSION],
[DETAILS],
[LG_SOURCE_TABLE],
[LG_TIME]
FROM
[MyTable] WITH (NOLOCK)
WHERE
CAST([LG_TIME] AS DATE) = '20190923'
--returns 19.879.488 rows
METHOD 3:
SELECT
*
FROM
[MyTable] WITH (NOLOCK)
WHERE
[LG_TIME] >= '20190923'
AND [LG_TIME] < '20190924'
--returns 19.880.186 rows
METHOD 4:
SELECT
*
FROM
[MyTable] WITH (NOLOCK)
WHERE
CAST([LG_TIME] AS DATE) = '20190923'
--returns 19.879.488 rows
И, как вы видите, у меня каждый раз разные наборы результатов.Я не понимаю, почему это происходит, я делаю что-то не так?Какой правильный / безопасный способ получения необходимых мне данных на основе диапазона даты и времени?
Я выполняю bcp out / in с рабочего сервера (который имеет 1,2 миллиарда строк, но скоро будет усечен) в архив(в котором 10,5 миллиардов строк), и иногда я теряю запись, потому что у них один и тот же [LG_TIME] (может быть, я создам другой вопрос об этом).
РЕДАКТИРОВАТЬ 1: Дополнительная информация:
- Запрос (МЕТОД 1) является частью процедуры BCP OUT, которая происходит ежедневно примерно в 00:05, а диапазон дат всегда одинаков, 2 текущих дня назад.
- У меня есть строгие рекомендациивсегда использовать WITH (NOLOCK) при запросах на производственных серверах.
- Есть миллионы строк, у которых LG_TIME = NULL в таблице, но эти строки устарели и будут удалены, я не знаю, являются ли эти строкивызвать какие-либо проблемы с моим запросом.
- Таблица является частью механизма ведения журнала приложения, только INSERTS происходят и удаляются очень рано утром (около 02: 00-03: 00), когда tЕжедневное архивирование - это успех.В этот раз никто не читает таблицу.
РЕДАКТИРОВАТЬ 2 (2019-09-26 10:30): Итак, я добавил LG_TIME IS NOT NULL
ко всем моим запросам, где критерии и это мои результаты:
МЕТОД 1:19.879.488 строк
МЕТОД 2: 19.879.488 строк
МЕТОД 3: 19.880.036 строк
МЕТОД 4: 19.879.488 строк
Все еще странно!