Почему запрос Select * FROM Table, в котором запрос ID NOT IN (список идентификаторов int) медленный в sql server ce? - PullRequest
3 голосов
/ 23 августа 2010

ну эта проблема вообще в sql server ce
у меня есть индексы на всех полях.
также тот же запрос, но с ID IN (список идентификаторов int) довольно быстрый.
Я попытался изменить запрос на OUTER Join, но это только усугубило ситуацию. Итак, есть ли намеки на то, почему это происходит и как решить эту проблему?

Ответы [ 3 ]

8 голосов
/ 23 августа 2010

Это потому, что индекс не очень полезен для такого рода запросов, поэтому база данных должна выполнить полное сканирование таблицы.Если запрос (по какой-то причине) медленнее, чем простой «SELECT * FROM TABLE», сделайте это вместо этого и отфильтруйте нежелательные идентификаторы в программе.вместо списка.Из-за этого есть три возможных способа сделать то же самое (возможно, один из них быстрее):

Исходное утверждение:

select * from mytable where id not in (select id from othertable);

Альтернатива 1:

select * from mytable where not exists 
   (select 1 from othertable where mytable.id=othertable.id);

Альтернатива 2:

select * from mytable
minus
select mytable.* from mytable in join othertable on mytable.id=othertable.id;

Альтернатива 3: (некрасиво и трудно понять, но если все остальное терпит неудачу ...)

select * from mytable
  left outer join othertable on (mytable.id=othertable.id)
  where othertable.id is null;
0 голосов
/ 23 августа 2010

ammoQ правильно, индекс не очень помогает с вашим запросом. В зависимости от распределения значений в столбце идентификаторов вы можете оптимизировать запрос, указав, какие идентификаторы следует выбирать, а не выбирать. Если вы в конечном итоге запросите, скажем, более ~ 25% индекса таблицы, в любом случае не будет использоваться, потому что для некластеризованного индекса (который является единственным типом индексов, который SQL CE поддерживает, если память обслуживает) будет дешевле сканировать таблицу. В противном случае (если запрос действительно избирательный) вы можете переписать запрос с диапазонами идентификаторов, чтобы выбрать («объединение всех» может работать лучше, чем «или» для объединения диапазонов, если SQL CE поддерживает «объединение всех», не уверен)

0 голосов
/ 23 августа 2010

Это проблема не SQL Server CE, а всей базы данных.

ОПЕРАЦИЯ IN - это sargable, а NOT IN - не sargable.

Что это значит?

Search ARGument Able, это означает, что механизм СУБД может воспользоваться преимуществами использования индекса, а для Non Search ARGument Ablee индекс не может быть использован.

Решением может быть использование оператора filter для удаления этих идентификаторов

Подробнее о настройке производительности SQL от Peter Gulutzan.

...