我在使用大量记录填充数据库时无法进行速度测试。任何人都可以告诉我在处理数百万条记录时哪个查询应该更快?我喜欢Tomas'查询最多,但是在处理更大的桌子时,DISTINCT不会放慢速度吗?
我很惊讶地看到我的子查询并没有像我想象的那样减慢速度。
::我的。在00.0640419中生成22行> 00.1030255秒。
SELECT
[planning].[id] as planningId,
[planning].[type] as planningType,
[planning].[from] as planningFrom,
[planning].[till] as planningTill,
[worker].[intId] as workerId,
[worker].[name] as workerName,
[site].[intId] as siteId,
[site].[name] as siteName
FROM
[worker]
LEFT JOIN [planning] ON [planning].[workerId] = [worker].[intId] AND [planning].[companyId] = [worker].[companyId]
LEFT JOIN [site] ON [planning].[siteId] = [site].[intId] AND [planning].[companyId] = [site].[companyId]
WHERE
[worker].[companyId] = 2
AND ( [planning].[id] IS NULL OR ( [planning].[from] <= '2014-04-30' AND [planning].[till] >= '2014-04-01') )
AND ([worker].[intId] IN (
SELECT
[worker].[intId]
FROM
[planning]
INNER JOIN [worker] ON [planning].[workerId] = [worker].[intId] AND [planning].[companyId] = [worker].[companyId]
WHERE
[worker].[companyId] = 2
AND ([planning].[type] = 'absent' OR ([planning].[siteId] IN ('7710122')))
) OR [worker].[intId] IN ('7701260')
)
:: Sirko。在00.0684108中生成22行&gt; 00.0955292秒。
SELECT
[planning].[id] as planningId,
[planning].[type] as planningType,
[planning].[from] as planningFrom,
[planning].[till] as planningTill,
[worker].[intId] as workerId,
[worker].[name] as workerName,
[site].[intId] as siteId,
[site].[name] as siteName
FROM
[worker]
LEFT JOIN [planning] ON [planning].[workerId] = [worker].[intId] AND [planning].[companyId] = [worker].[companyId]
LEFT JOIN [site] ON [planning].[siteId] = [site].[intId] AND [planning].[companyId] = [site].[companyId]
LEFT JOIN ( SELECT DISTINCT
[worker].[intId]
FROM
[planning]
LEFT JOIN [worker] ON [planning].[workerId] = [worker].[intId] AND [planning].[companyId] = [worker].[companyId]
WHERE
[worker].[companyId] = 2
AND ([planning].[type] = 'absent' OR ([planning].[type] = 'site' AND [planning].[siteId] IN ('7710122')))
) AS filter ON filter.[intId] = [worker].[intId]
WHERE
[worker].[companyId] = 2
AND ( ( [planning].[from] <= '2014-04-30' AND [planning].[till] >= '2014-04-01') OR [worker].[intId] IN ('7701260') )
:: Tomas Pastircak。在00.0674178中生成22行> 00.0850567秒。
SELECT DISTINCT
[planning].[id] as planningId,
[planning].[type] as planningType,
[planning].[from] as planningFrom,
[planning].[till] as planningTill,
[worker].[intId] as workerId,
[worker].[name] as workerName,
[site].[intId] as siteId,
[site].[name] as siteName
FROM
[worker]
LEFT JOIN [planning] ON [planning].[workerId] = [worker].[intId] AND [planning].[companyId] = [worker].[companyId]
LEFT JOIN [site] ON [planning].[siteId] = [site].[intId] AND [planning].[companyId] = [site].[companyId]
LEFT JOIN [planning] p2 ON p2.[workerId] = [worker].[intId] AND p2.[companyId] = [worker].[companyId]
WHERE
[worker].[companyId] = 2
AND ( [planning].[id] IS NULL OR ( [planning].[from] <= '2014-04-30' AND [planning].[till] >= '2014-04-01') )
AND (p2.[type] = 'absent' OR p2.[siteId] IN ('7710122') OR [worker].[intId] IN ('7701260'))
答案 0 :(得分:1)
有没有理由为什么你不能将它添加到WHERE条件中,没有所有子查询的东西?它似乎返回相同的数据......
SELECT
...
FROM
...
LEFT JOIN [planning] p2 ON p2.[workerId] = [worker].[intId] AND p2.[companyId] = [worker].[companyId]
WHERE
[worker].[companyId] = 2
AND ( [planning].[id] IS NULL OR ( [planning].[from] <= '2014-04-30' AND [planning].[till] >= '2014-04-01') )
AND (p2.[type] = 'absent' OR (p2.[type] = 'site' AND p2.[siteId] IN ('7710122'))
答案 1 :(得分:1)
我并不完全熟悉T-SQL语法,但以下内容应该有效:
SELECT
[planning].[id] as planningId,
[planning].[type] as planningType,
[planning].[from] as planningFrom,
[planning].[till] as planningTill,
[planning].[busyMon] as busyMon,
[planning].[busyTue] as busyTue,
[planning].[busyWed] as busyWed,
[planning].[busyThu] as busyThu,
[planning].[busyFri] as busyFri,
[planning].[busySat] as busySat,
[planning].[busySun] as busySun,
[planning].[busyHolidays] as busyHolidays,
[worker].[intId] as workerId,
[worker].[name] as workerName,
[worker].[partner] as workerPartner,
[site].[intId] as siteId,
[site].[name] as siteName
FROM
[worker]
LEFT JOIN [planning] ON [planning].[workerId] = [worker].[intId] AND [planning].[companyId] = [worker].[companyId]
LEFT JOIN [site] ON [planning].[siteId] = [site].[intId] AND [planning].[companyId] = [site].[companyId]
LEFT JOIN ( SELECT DISTINCT
[worker].[intId]
FROM
[planning]
LEFT JOIN [worker] ON [planning].[workerId] = [worker].[intId] AND [planning].[companyId] = [worker].[companyId]
WHERE
[worker].[companyId] = 2
AND ([planning].[type] = 'absent' OR ([planning].[type] = 'site' AND [planning].[siteId] IN ('7710122','123456')))
) AS filter ON filter.[intId] = [worker].[intId] OR [worker].[intId] IN ('987654','654321')
WHERE
[worker].[companyId] = 2
AND ( [planning].[id] IS NULL OR ( [planning].[from] <= '2014-04-30' AND [planning].[till] >= '2014-04-01') )
答案 2 :(得分:0)
这不是一个完整的答案,但我的观点在评论中并不好,所以我会把它放在这里。
从一开始,你的大子查询似乎不对:
SELECT worker.intId
FROM planning
LEFT JOIN
worker ON planning.workerId = worker.intId
AND planning.companyId = worker.companyId
WHERE worker.companyId = 2
AND ( planning.type = 'absent'
OR ( planning.type = 'site'
AND planning.siteId IN ('7710122','123456')
)
)
从计划到工人的LEFT JOIN与worker.companyId = 2结合将导致INNER JOIN。
你能用语言澄清你想用子查询完成什么吗?