在SQL Server实例上,我有以下表格:
CREATE TABLE [dbo].[DIALPLAN](
[IdDialPlan] [int] IDENTITY(1,1) NOT NULL,
[Prefixe] [varchar](500) NOT NULL,
[Type] [varchar](255) NOT NULL,
[Country] [varchar](255) NOT NULL,
[Description] [varchar](255) NOT NULL,
CONSTRAINT [PK_TMP_DIALPLAN] PRIMARY KEY CLUSTERED
(
[IdDialPlan] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
CONSTRAINT [CK_TMP_DIALPLAN_UNIQUE] UNIQUE NONCLUSTERED
(
[Prefixe] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
CREATE TABLE [dbo].[CALLS](
[uniqueid] [varchar](150) NULL,
[accountcode] [varchar](20) NULL,
[OutTel] [varchar](80) NULL,
[lastapp] [varchar](80) NULL,
[lastdata] [varchar](200) NULL,
[CallLocalTime] [datetime] NULL,
[answer] [datetime] NULL,
[CallEnd] [datetime] NULL,
[duration] [int] NULL,
[CallDuration] [int] NULL,
[disposition] [varchar](20) NULL,
[Destination] [text] NULL,
[Asterisk] [varchar](20) NULL,
[Endreason] [varchar](20) NULL,
[CLI] [varchar](80) NULL
)
DIALPLAN
表包含所有电话号码前缀(100K行),字段Prefixe
包含前缀值(例如加拿大艾伯塔省1403或法国移动Bouygues 33665)和{{1} } table包含电话呼叫(始终选择一批1K行)。以下查询的目的是为每个电话号码找到正确的前缀(CALLS
表的字段OutTel
)。正确的前缀是与电话号码匹配的最长前缀:
CALLS
有没有其他方法可以在更短的时间内获得相同的结果?
编辑1:
这是解决方案1的执行计划:
这是解决方案2的执行计划:
编辑2:
这是一些示例数据
-- Solution 1 4200ms : Sort 40% Top 10%
SELECT TOP 1000 SUBSTRING(OutTel,3,LEN(OutTel)), FN.IdDialPlan, FN.Description
FROM [dbo].[CALLS]
CROSS APPLY (SELECT TOP 1 IdDialPlan, Description FROM [dbo].[DIALPLAN] dp WHERE dp.Prefixe = LEFT(SUBSTRING(OutTel,3,LEN(OutTel)),LEN(dp.Prefixe)) ORDER BY LEN(Prefixe) DESC) AS FN
-- Solution 2 3400ms : Sort(Join) 50%
SELECT TOP 1000 SUBSTRING(calls.OutTel,3,LEN(calls.OutTel)), dp.IdDialPlan, dp.Description
FROM [dbo].[CALLS] calls LEFT JOIN [dbo].[DIALPLAN] dp ON dp.Prefixe = LEFT(SUBSTRING(calls.OutTel,3,LEN(calls.OutTel)),LEN(dp.Prefixe))
表CALLS
字段仅用于显示目的
OutTel
OutTel
----------------
0033170448508
0033155373050
0021620383555
0016465699156
00390689971917
表
DIALPLAN
感谢。
答案 0 :(得分:0)
看起来您需要进行结构更改,因为您的索引总是会因为函数的连接而被搜索,而这些类型是您的TOP运算符。
您可以尝试使用max()而不是top 1,但是你可以在那里使用Description,因此它不起作用。
您可以创建一个映射表,该表将通过聚集索引填充您的2个表(希望它是一个存储过程而不是实体框架)填充,因此它会预先排序您的列,但它会减慢您的插入和更新。它还可以解决您的索引扫描操作。