Неожиданное сканирование таблицы на предмет идентификатора! = идентификатор

Уэлп, я кое-что понял. Я использую RSS API и могу отправлять запросы таким образом. Так эй Если это работает, это работает.

11
задан Ian Elliott 14 July 2009 в 02:15
поделиться

13 ответов

Прочитав здесь ответы и ваши правки, позвольте мне подытожить ваши варианты:

  1. Измените MS SQL Server для обработки этого случая (в основном, обратитесь в службу поддержки Microsoft)
  2. Измените приложение, чтобы избежать этого случая, или сделайте это по-другому (в основном, поговорите со службой поддержки компании, которая сделала приложение)
  3. Измените на что-то, кроме SQL Server (если приложение позволяет это), который обрабатывает этот случай
  4. Изменить в другое приложение

Ни одно из этих решений не является хорошим, но, к сожалению, они единственные, которые у вас есть. Вы должны выбрать одно и следовать ему.

Сначала я бы попробовал решение 2, это то, на выполнение которого / должно потребоваться наименьшее время.

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

2
ответ дан 3 December 2019 в 03:05
поделиться

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

0
ответ дан 3 December 2019 в 03:05
поделиться

Я подозреваю, что SqlServer "не знает", что! = (Должно быть "<>"?) Является антирефлексивным (т.е. A! = A всегда ложно) ... это просто убедитесь, что он не постоянный (он зависит от значений из строки результата) и, следовательно, помещает его в фильтр результатов. Итак, «where id <> id» потенциально сильно отличается от «where 1 <> 1».

Теперь они определенно могут заставить его обнаружить этот случай; но я полагаю, что это просто никогда не попадало в их список приоритетов, потому что делать это где-то между "странным" и "глупым".

Да, приложение, которое делает это, отстой, я думаю, вы это уже знаете;)

1
ответ дан 3 December 2019 в 03:05
поделиться

Мне кажется, у вас политическая проблема, маскирующаяся под техническую. Вы можете потратить много времени и усилий на решение технической проблемы, но пока вы продолжаете повторять «мы не контролируем приложение», вы закрываете себя от преследования политических вариантов.

Вы не можете контролировать app, но вы, вероятно, можете организовать какое-то влияние. Сообщите всем заинтересованным сторонам, как поведение этого приложения влияет на всех остальных, кто использует эту базу данных (используйте графики, так как вы захотите быстро передать это сообщение руководству). И дайте понять, что эту проблему должен исправить автор приложения или Microsoft. Это может привести к давлению на автора приложения или может дать ответ «Хорошо, хорошо. Давайте купим другую базу данных для этого приложения».

1
ответ дан 3 December 2019 в 03:05
поделиться

Будучи менее знакомым с SQL Server, я думаю, что приведенное ниже решение также может применяться к SQL Server.

В Oracle я думаю, что вы можете перехитрить наивный SQL, используя материализованное представление и переписывая запросы , Материализованное представление не будет содержать строк, а перезапись запроса распознает SQL и вместо этого перенаправит запрос на пустое представление. Материализованное представление никогда не потребуется обновлять, так как оно всегда будет пустым.

1
ответ дан 3 December 2019 в 03:05
поделиться

Мне почти стыдно представить этот ответ, но в духе «если ничего разумного не работает, попробуйте безумное» ...

    Create a constraint on the table where id = id?

Предложение where могло возвращать только строки, нарушающие ограничение, из которых нет по определению. Эта дополнительная (хотя и избыточная) информация может помочь оптимизатору в вашем случае. Он также может получить квадратный корень из ничего, но в вашем случае я бы попробовал на всякий случай ...

2
ответ дан 3 December 2019 в 03:05
поделиться

Я не знаю, почему id! = id так long в этом случае (хотя "очевидное" субъективно - это не обязательно оптимизация, о которой я бы подумал ... это кажется необычным запросом; однако декартово соединение болезненно). Но в целом попробуйте «where 1 = 0» - или, если вам просто нужна схема, возможно, немного рискованное SET FMTONLY ON .

Изменить: только что увидел «Мы не контролируем приложение, которое выполняет этот запрос сотни раз в минуту "... хммм ... это усложняет задачу.

1
ответ дан 3 December 2019 в 03:05
поделиться

You might want to let the SQL Server support team know about this query (id <> id when the column is defined as a primary key) and the full table scan it causes, and to see if maybe they might want to add in an optimization in the query engine to ensure this doesn't cause a full table scan.

Either that, or talk to the support team of the app you can't control.

EDIT: Try the TechNet forum at http://social.msdn.microsoft.com/forums/en-US/sqldatabaseengine/threads/ to report the behavior.

3
ответ дан 3 December 2019 в 03:05
поделиться

I have seen this type of query.

Most likely the developers are building 'WHERE' clauses based on user input, current settings or some other factors. In many instances, maybe the default instance, they would need a WHERE clause that's just a placeholder. That's when they use criteria like 'id != id', '1 <> 1', etc.

The 'hundreds of times a minute' also leads me to believe that this is some misguided default placeholder.

Sometimes they'll use a criteria that does the opposite, always evaluates to true if the default case requires all the rows.

It's a long shot, but my suggestion would be to see if you can modify the application settings and see if this query goes away. You may end up with a small resultant set, but something that is run less frequently and better handled by SQL Server.

3
ответ дан 3 December 2019 в 03:05
поделиться

You're biggest problem isn't the table scan. Your two biggest problems are:

  • You have an absolutely useless query running 100's of times per minute against your database. My guess BTW, is that the query is actually trying to get the column names from the table as Marc Gravell suggests.

and more importantly:

  • You don't have control over who or what is accessing your database.

That second problem especially is going to most likely cause you endless headaches. Assuming that you are part of the data team in your organization (since you're the one trying to solve this problem), you really should be looking to make the organizational changes necessary to do your job.

Good luck!

4
ответ дан 3 December 2019 в 03:05
поделиться

Каждое значение сравнивается с остальными n-1 значениями. именно поэтому он возвращает огромное количество «Приблизительное количество строк». Для вышеупомянутой проблемы лучше использовать not in.

Эта статья - хороший указатель на вашу проблему. Надеюсь, это вам поможет. http://www.sqlservercentral.com/articles/Performance+Tuning/2924/

3
ответ дан 3 December 2019 в 03:05
поделиться

I would fake this query out... abstract away with a view, and dupe the query.

Rename your existing table 'table' to 'table_org' or something else, and create a view like this:

CREATE VIEW table
AS
SELECT * FROM table_org
WHERE id='BOGUSKEY'

Now, you should get your 1 scan through the table on the primary key, and it should (like the original query) find nothing. The application knows none the wiser...

6
ответ дан 3 December 2019 в 03:05
поделиться

Do you have a nonclustered index on the id column? If not, the most efficient course is always going to be a CIX scan. Try adding a NCIX on the ID column - it may still perform a scan, but at least it will be a scan on a very small index. If you were on SQL Server 2008, you could create a filtered index (WHERE id <> id), and SQL Server would use the (empty) filtered index to satisfy the query.

2
ответ дан 3 December 2019 в 03:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: