SQL IN плохо влияет на производительность? - PullRequest
57 голосов
/ 18 июня 2009

У меня есть запрос, выполняющий что-то вроде:

SELECT FieldX, FieldY FROM A
WHERE FieldW IN (108, 109, 113, 138, 146, 160,
307, 314, 370, 371, 441, 454 ,457, 458, 479, 480,
485, 488, 490, 492, 519, 523, 525, 534, 539, 543,
546, 547, 550, 564, 573, 629, 642, 643, 649, 650,
651, 694, 698, 699, 761, 762, 768, 772, 773, 774,
775, 778, 784, 843, 844, 848, 851, 852, 853, 854,
855, 856, 857, 858, 859, 860, 861, 862, 863, 864,
865, 868, 869, 871, 872, 873, 891) 

Имеет предложение IN с таким количеством опций, плохо ли это для производительности запросов? Я испытываю много тайм-аутов в своем приложении, и я считаю, что это может быть источником такой проблемы. Можно ли оптимизировать запрос, не удаляя цифры, используя любую хорошую подсказку SQL?

EDIT:

@ KM это ключи в другой таблице. Это приложение для форума, кратко объясняющее: c # получает все форумы из базы данных и сохраняет их в кеше приложения. Прежде чем C # вызывает процедуру, которая получает потоки для этих форумов и для этого пользователя, c # выполняет некоторую логику, фильтруя коллекцию "все форумы", учитывая разрешения и некоторую бизнес-логику. Тайм-аут происходит в базе данных, а не в самом приложении. Выполнение всей этой логики в запросе потребует большого количества внутренних соединений, и я не уверен на 100%, что смогу сделать все это внутри процедуры.

Я использую SQL Server 2000

Ответы [ 14 ]

1 голос
/ 18 июня 2009

Обычно предложение IN вредно для производительности, но то, что «плохо», зависит от приложения, данных, размера базы данных и т. Д. Вам нужно протестировать собственное приложение, чтобы увидеть, что лучше.

0 голосов
/ 18 июня 2009

Вы можете попробовать что-то вроде:

select a.FieldX, a.FieldY
from (
    select FieldW = 108 union
    select FieldW = 109 union
    select FieldW = 113 union
    ...
    select FieldW = 891
) _a
join A a on a.FieldW = _a.FieldW

Это может подходить для вашей ситуации, например, когда вы хотите динамически генерировать один оператор SQL. На моем компьютере (SQL Server 2008 Express) при тестировании с небольшим числом (5) значений FieldW и большим числом (100 000) строк в A используется поиск индекса по A с объединением вложенных циклов между A и _a что, вероятно, то, что вы ищете.

0 голосов
/ 18 июня 2009

Если вы можете использовать другие вещи, кроме IN: сделайте это (я использовал IN в некоторых случаях не совсем хорошим способом: я легко могу заменить существующим, и это быстрее)

В вашем случае: кажется, не так уж и плохо.

0 голосов
/ 18 июня 2009

Производительность может быть оценена только в контексте того, что вы пытаетесь сделать. В этом случае вы запрашиваете извлечение около 70 строк (при условии, что они являются уникальными значениями), поэтому вы можете ожидать что-то примерно в 70 раз больше времени извлечения одного значения. Это может быть меньше из-за кэширования или курса.

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

...