我有一个穷人的复制设置,我无能为力。来自 a 的一些标识数据(基本上是主键)call_table
通过简单的触发器复制到另一个表中,然后“复制服务器”运行存储过程将数据从队列表复制到 #temp 表(以防止 SQL 中的锁定) 6.5是给我的情况)。call_table
最后,查询使用临时表中的关键数据将数据从使用此查询拉回复制服务器:
/* select the data to return to poor man replication server */
SELECT c.id,
c.date,
c.time,
c.duration,
c.location
FROM #tmp q, call_table c (NOLOCK)
WHERE q.id=c.id
AND q.date=c.date
AND q.time=c.time
AND q.duration=c.duration
AND q.location=c.location
GROUP BY c.id,
c.date,
c.time,
c.duration,
c.location
每天晚上清理一次队列表,然后重新开始。在对此进行调查时,隐式交叉连接向我扑来(我站在他们通常是邪恶的一边),但后来我读到了交叉连接的力量。我在这里是因为我不太相信。假设 temp 表一天有大约 10,000 行,call_table 到目前为止一个月有大约 100,000 行。这个查询将如何工作?它是否将这两个表混合在一起,总共有 1,000,000,000 个内存,然后使用 group 子句将其修剪下来?你能解释一下 SQL 编译结果的步骤吗?
执行计划:
My Query:
|--Hash Match Root(Aggregate, HASH:([c].[id], [c].[date], [c].[location], [c].[time], [c].[duration]), RESIDUAL:(((((((((((((((((((((([c].[id]=[c].[id] AND [c].[PIN]=[c].[PIN]) AND [c].[ORIG]=[c].[ORIG]) AND [c].[date]=[c].[date]) AND [c].[CTIME]=[c].[CTIME
|--Hash Match Team(Inner Join, HASH:([q].[id], [q].[date], [q].[location], [q].[time], [q].[duration])=([c].[id], [c].[date], [c].[location], [c].[time], [c].[duration]), RESIDUAL:(((([c].[id]=[q].[id] AND [c].[location]=[q].[location]) AND [c].[duration]=[q].[duration]) AND [
|--Table Scan(OBJECT:([db].[dbo].[queue] AS [q]))
|--Table Scan(OBJECT:([db].[dbo].[call_table] AS [c]))
Yours:
|--Merge Join(Right Semi Join, MERGE:([q].[id], [q].[date], [q].[time], [q].[duration], [q].[location])=([c].[id], [c].[date], [c].[time], [c].[duration], [c].[location]), RESIDUAL:(((([q].[id]=[c].[id] AND [q].[location]=[c].[location]) AND [q].[duration]=[c].[duration]) AND [q].[
|--Index Scan(OBJECT:([db].[dbo].[queue].[PK_queue] AS [q]), ORDERED)
|--Sort(ORDER BY:([c].[id] ASC, [c].[date] ASC, [c].[time] ASC, [c].[duration] ASC, [c].[location] ASC))
|--Table Scan(OBJECT:([db].[dbo].[call_table] AS [c]))