Комментарии 18
PS а статья-то того… капельку несвежая. 7 лет скоро будет.
У меня есть вью с объединением внутри. Что я делаю не так? Явно определяю список колонок вместо звёздочки?
А вообще-то, когда меня учат использовать недокументированные возможности (по аналогии с чёрной и белой магией программирования, когда всё по правилам, но тщательно укрыто под капотом, я назвал бы это шаманством), у меня в мозгу звенит звонок и нервно мигает лампочка.
Возможно, это может быть полезно на проекте, который работает ровно в одном месте, с определёнными, но не известными настройками и набором данных. А когда, как у меня, куча филиалов, разные данные и разные версии (последний sql 2000) вынесли из эксплуатации пару месяцев назад), главное правило — будь проще и конкретнее. Проси у сервера именно то, что тебе надо, а не "то, как, может быть, но это не точно, сервер хотел бы видеть мой запрос".
Хотя в целом конкретно MS SQL из-за особенностей хранения любит сваливаться в Clustered Index Scan, так как он в обычных индексах хранит значение именно из Clustered Index, и ему нужно по сути два раза поиск делать (в том же PostgreSQL не надо, но там и другие проблемы из-за этого). Но если MS SQL в итоге переходит на Clustered Index Scan, то как правило так на самом деле не сильно медленнее.
Для того, чтобы не делать "два раза поиск" (видимо, имеется ввиду index seek + key lookup) — в MSSQLSEVER имеются покрывающие индексы.
Это когда часть информации хранится в самом индексе. По факту — эта такая рядомлежащая теневая табличка, с узким подмножеством полей из основной таблицы с другим кластерным индексом.
Разумеется, наличие покрывающих индексов удорожает операции модификации данных, но позволяет иногда ускорить селекты на пару-тройку порядков.
Общее правило: увидел seek + lookup в плане — посмотри, какие поля подтягиваются в лукапе. Иногда энжин не хватает буквально одного — двух полей.
Добавьте их в include индекса, если это не сделает индекс слишком тяжелым, и, возможно, производительность вашего запроса вырастет.
… На пару порядков.
вместо WHERE ProductID = 750 OR ProductID = 953
сделал WHERE ((ProductID = 750) OR (ProductID = 953))
Буквально на днях в статье про стендапы в Яндекс.Такси обсуждался такой кейс.
Если нагрузка уже упёрлась в диск (или близко к этому) — то пользы не будет.
в целом я согласен с мнением, высказанным выше: кривая статистика, и только.
P.S. уровень оригинальной статьи очень слабый, я надеялся увидеть тут интересные случаи, в которых оптимизатор не справляется, а union помогает направить его в нужное русло, а тут…
Ну, не все йогурты одинаково полезны.
При использовании union вместо or или in — вы рискуете получить избыточную дедубликацию результирующей выборки.
Так что нужно отчетливо понимать, что и зачем вы делаете.
Впрочем, как и всегда в жизни.
:-)
И, кстати, столкнувшись с подобным поведением запроса, прежде чем резать его пополам (хотя это частенько бывает нужно) — обновите статистику. Может странности и пройдут.
Использование Union вместо OR