Рассмотрим эту разницу производительности SQL, где в первую очередь я выбираю все 26 000 строк, а во втором я просто хочу первые 5.
SELECT tw.*
FROM entity e
JOIN entity_tag et on et.entity_id = e.id
JOIN tag t on t.tag_id = et.tag_id
JOIN tagrelatedtweets trt on trt.FK_Tag_ID = t.tag_id
JOIN tweets tw on tw.PK_Tweet_ID = trt.FK_Tweet_ID
WHERE e.id = 765131
ORDER BY tw.[timestamp]
против
SELECT TOP (5) tw.*
FROM entity e
JOIN entity_tag et on et.entity_id = e.id
JOIN tag t on t.tag_id = et.tag_id
JOIN tagrelatedtweets trt on trt.FK_Tag_ID = t.tag_id
JOIN tweets tw on tw.PK_Tweet_ID = trt.FK_Tweet_ID
WHERE e.id = 765131
ORDER BY tw.[timestamp]
Without: CPU = 201 | Reads: 6880 | Writes: 0 | Duration: 451
With: CPU = 302439 | Reads: 7453199 | Writes: 3169 | Duration: 74188
это просто не имеет смысла Мне ... Есть ли другой способ поступить об этом?
После предложения Мартина о восстановлении статистики на всех задействованных таблицах есть небольшое улучшение, но хитрость с изменением верхней суммы в параметр работает лучше всего.
До восстановления статистики:
CPU = 302439 | Reads: 7453199 | Writes: 3169 | Duration: 74188
после восстановления статистики:
CPU = 127734 | Reads: 4100436 | Writes: 2656 | Duration: 16880
с параметром:
CPU = 218 | Reads: 6899 | Writes: 0 | Duration: 83
запрос с параметром:
DECLARE @TOP INT; SET @TOP=5;
SELECT TOP (@TOP) tw.*
FROM entity e
JOIN entity_tag et on et.entity_id = e.id
JOIN tag t on t.tag_id = et.tag_id
JOIN tagrelatedtweets trt on trt.FK_Tag_ID = t.tag_id
JOIN tweets tw on tw.PK_Tweet_ID = trt.FK_Tweet_ID
WHERE e.id = 765131
ORDER BY tw.timestamp desc
Последнее замечание для тех из вас, что использует структуру объекта; Если вы испытываете это поведение, вы можете моделировать одно и то же поведение на основе параметра следующим образом:
.Take(100).ToList().Take(5)
Я знаю, что это не красиво, но это единственный способ вызвать правильный план выполнения, если вы используете структуру Entity могу сказать.
Большое спасибо, чтобы указывать мне в правильном направлении Мартина!