Запрос зависает с INNER JOIN в поле даты и времени - PullRequest
0 голосов
/ 27 января 2009

У нас странная проблема с объединением таблиц из SQL Server 2005 и MS Access 2003.

Существует большая таблица на сервере и довольно маленькая таблица локально в Access. Таблицы объединяются через 3 поля, одно из которых - поле даты и времени (содержащее день; идея состоит в том, чтобы извлекать дополнительные данные (ежедневно) из большой таблицы серверов, чтобы добавить данные в локальную таблицу).

Вплоть до выходных это работало каждый день. Со вчерашнего дня мы столкнулись со странными тайм-аутами в Access с этим запросом. Отсутствие времени ожидания означает, что запрос выполняется всегда с довольно высокой скоростью передачи по сети, но время ожидания не происходит. Доступ даже не показывает индикатор выполнения. Трассировка сервера говорит нам, что один и тот же запрос выполняется на сервере SQL снова и снова без ошибок, но и без результата. Мы сузили ее до проблемы, которая, по-видимому, связана с доступом к таблице серверов с большой таблицей и с JOIN или WHERE, содержащей дату, но на самом деле мы не можем сузить ее. Мы уже перестроили индексы и в настоящее время восстанавливаем резервные данные, но, возможно, у кого-то здесь есть какие-то указатели того, что мы могли бы попробовать.

Спасибо, Майк.

Ответы [ 6 ]

1 голос
/ 23 июля 2009

Если вы присоединяете локальную таблицу в Access к связанной таблице в SQL Server, и запрос на самом деле не тривиален в соответствии с конкретными ограничениями присоединений к связанным данным, вполне вероятно, что Access получит всю таблицу из SQL Server и выполнить объединение локально против всего набора. Это известная проблема.

Это напрямую не касается вопроса, который вы задаете, но как далеко вы располагаете всеми данными в одном месте (SQL Server)? ИМХО, вы можете ожидать, что одни и те же проблемы с производительностью будут преследовать вас, если у вас есть данные в каждой системе.

Если бы все это было в SQL Server, сквозной запрос оптимизировал бы и использовал доступные индексы и т. Д.

1 голос
/ 27 января 2009

Спасибо за быстрый ответ!

Фактический запрос действительно огромен; Вы не будете счастливы с этим:)

Однако мы сократили его до простого:

SELECT * FROM server_table INNER JOIN access_table ON server_table.date = local_table.date;

Если server_table - это большая таблица (трудно сказать, у нас в ней 1,5 миллиона строк; тестовые таблицы с 10 строками или около того работают), а local_table - это таблица с одной ячейкой, содержащей дату. Это работает вечно. Он не только медленный, он просто ничего не делает, кроме того - кажется, что он вызывает сетевой трафик и не делает тайм-аут (это то, что я нахожу настолько странным; обычно вы получаете тайм-аут, но это просто продолжает работать).

Мы только что нашли статью KB 828169; кажется, наша проблема, мы рассмотрим это. Спасибо за вашу помощь!

0 голосов
/ 23 июля 2009

Попробуйте другой синтаксис? Что-то вроде: <br> SELECT * FROM BigServerTable b WHERE b.DateFld in (SELECT DISTINCT s.DateFld FROM SmallLocalTable s)
Странная вещь в описании вашей проблемы: «До выходных этот день работал нормально каждый день». Это означало бы, что проблема действительно где-то еще.
Вы пытались создать новую пустую базу данных Access и импортировать все из старого?
Или просто обновить все ваши ссылки?

0 голосов
/ 19 мая 2009

Используйте функцию DATEDIFF для сравнения двух дат следующим образом:

'DATEDIFF возвращает 0, если даты идентичны на основе параметра datepart, в данном случае d

WHERE DATEDIFF(d,Column,OtherColumn) = 0

DATEDIFF оптимизирован для использования с датами. Сравнение результата функции CONVERT по обеим сторонам знака равенства (=) может привести к сканированию таблицы, если любая из дат будет NULL.

Надеюсь, это поможет,

Bill

0 голосов
/ 28 января 2009

Просто идея, но в SQL Server вы можете присоединить свою базу данных Access и использовать таблицу там. Затем можно создать представление на сервере, чтобы выполнить объединение всех в SQL Server. Решение, предложенное в статье базы знаний, кажется мне проблематичным, так как это клочок (если LIKE работает, то = должен также)

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

0 голосов
/ 27 января 2009

Пожалуйста, опубликуйте запрос, который делает это, только потому, что у вас есть индексы, не означает, что они будут использоваться. Если ваше предложение WHERE или JOIN не может быть sargable, то индекс не будет использоваться

возьмите это например

WHERE CONVERT(varchar(49),Column,113) =  CONVERT(varchar(49),OtherColumn,113)

, который не будет использовать индекс

или это

WHERE YEAR(Column) = 2008

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

Мы уже перестроили индексы и в настоящее время восстанавливаем резервные данные, но, возможно, у кого-то здесь есть какие-то указатели того, что мы могли бы попробовать.

Доступ может убить много хороших вещей ... Вы когда-нибудь задумывались о блокировке

пробег

exec sp_who2

посмотрите на столбец BlkBy и посмотрите, кто что блокирует

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