Задача: найти все тройки чисел (n1, n2, n3)
от 1 до 512 так, чтобы n1=n2*n3
.Использование только чистого SQL и никаких ожидаемых ранее табличных пространств, а также создание новых постоянных таблиц.
Решение CTE:
;with two as
(
select 0 as ID union select 1 as ID
), eight as
(
select t1.ID*4+t2.ID*2+t3.ID as ID
from two t1 inner join two t2 on 1=1 inner join two t3 on 1=1
), halfk as
(
select t1.ID*8*8 + t2.ID*8 + t3.ID + 1 as ID
from eight t1 inner join eight t2 on 1=1 inner join eight t3 on 1=1
)
select t1.ID, t2.ID, t3.ID
from halfk t1
inner join halfk t2 on t1.ID % t2.ID = 0
inner join halfk t3 on t3.ID * t2.ID = t1.ID
Продолжительность: не знаю;остановлено почти через 2 минуты.
Решение временной таблицы:
if (object_id('tempdb..#tmp_two', 'U') is not null) drop table #tmp_two
select 0 as ID into #tmp_two union select 1 as ID
if (object_id('tempdb..#tmp_eight', 'U') is not null) drop table #tmp_eight
select t1.ID*4+t2.ID*2+t3.ID as ID into #tmp_eight
from #tmp_two t1 inner join #tmp_two t2 on 1=1 inner join #tmp_two t3 on 1=1
if (object_id('tempdb..#tmp_halfk', 'U') is not null) drop table #tmp_halfk
select t1.ID*8*8 + t2.ID*8 + t3.ID + 1 as ID into #tmp_halfk
from #tmp_eight t1 inner join #tmp_eight t2 on 1=1 inner join #tmp_eight t3 on 1=1
select t1.ID, t2.ID, t3.ID as ID
from #tmp_halfk t1 inner join #tmp_halfk t2 on t1.ID % t2.ID = 0
inner join #tmp_halfk t3 on t3.ID * t2.ID = t1.ID
Продолжительность: 1 секунда.
Вопрос : почему производительностьтакие разные?Почему таблицы CTE не материализуются, даже если они использовались в описанном выше решении более одного раза?
Что еще более важно, так как это оказывает огромное влияние на производительность, как я могу избежать использования чистого и аккуратного способа выполнения работы, но путем внедренияриск производительности?Есть ли какие-либо рекомендации, чтобы избежать подобных случаев?
select @@VERSION
Microsoft SQL Server 2016 (SP1-CU10-GDR) (KB4293808) - 13.0.4522.0 (X64) Jul 17 2018 22:41:29 Copyright (c) Microsoft Corporation Enterprise Edition (64-bit) on Windows Server 2012 R2 Datacenter 6.3 <X64> (Build 9600: ) (Hypervisor)