视图优化中的子查询

时间:2015-01-14 19:31:40

标签: sql sql-server performance optimization

我有一个从两个表CallCaller读取的视图,这两个表是并行的,因为它们被键入相同的ID(即获取呼叫的来电者信息,你加入Call.id = Caller.id)。我有一个视图,跨越这两个表,以返回有关任何特定调用或一组调用的复合信息。

但是我在该视图中有一个子查询用于确定呼叫者是否已被回叫(定义为在此呼叫之后对状态为已完成的同一电话号码进行了另一次呼叫)。此子查询使查询查询速度极慢,但我不确定包含此信息的更好方法。以下是相关的DDL,想法?

编辑:如果添加了一些索引,这个查询会好吗?还是有更有效的方法来构建查询本身?

CREATE TABLE [CALL]
(
    ID VARCHAR(64) PRIMARY KEY, --this is a legacy system, I know varchar(64) isn't an efficient primary key
    CALLDATE DATETIME,
    STATUS BIT --1 = Complete, 0 = Incomplete
)

CREATE TABLE [CALLER]
(
    ID VARCHAR(64) PRIMARY KEY,
    PHONENUMBER VARCHAR(10),
    FIRSTNAME VARCHAR(50),
    LASTNAME VARCHAR(50)
)

CREATE VIEW [CALLVIEW] AS
SELECT
    CALL.ID AS CALLID,
    CALL.CALLDATE AS CALLDATE,
    CALL.STATUS AS CALLSTATUS,
    CALLER.PHONENUMBER AS PHONENUMBER,
    CALLER.FIRSTNAME AS FIRSTNAME,
    CALLER.LASTNAME AS LASTNAME,
    CAST(CASE WHEN EXISTS (SELECT TOP 1 1
                           FROM [CALL] CALL2
                           INNER JOIN [CALLER] CALLER2 ON CALL2.ID = CALLER2.ID
                           WHERE CALLER2.PHONENUMBER = CALLER.PHONENUMBER
                           AND CALL2.CALLDATE > CALL.CALLDATE
                           AND CALL2.STATUS = 1) THEN 1 ELSE 0 END AS BIT) AS CALLEDBACK
FROM
    [CALL]
    INNER JOIN [CALLER] ON [CALL].ID = [CALLER].ID

编辑:从执行计划中我注意到,到目前为止,查询中最昂贵的组件如下:

Clustered Index Seek

谓词:CALL2.CALLDATE> CALL.CALLDATE和CALL2.STATUS = 1

对象:[CALL]。[PK_CALL] CALL2(所以它使用主键索引)

输出列表:[CALL] .CALLDATE,[CALL] .STATUS

寻求谓词:[CALL] .id =标量运算符([CALLER] .id)

索引搜寻

对象:[CALLER]。[IX_PHONENUMBER] CALLER2(所以它使用正确的索引但仍然很昂贵?)

输出列表:[CALLER] .ID

寻求谓词:[CALLER]。PHONENUMBER =标量运算符([CALLER] .PHONENUMBER)

1 个答案:

答案 0 :(得分:1)

首先,尝试使用数据库引擎优化顾问,它会告诉您是否需要创建一些索引。

无论如何,这就是我要做的事情:

  • 确认您在CALL.ID和CALLER.ID上实际拥有CLUSTERED索引(作为遗留系统,可能您有PK,但有人删除了索引)
  • 创建非聚集索引:
    • CALLER.PHONENUMBER
    • CALL.CALLDATE
    • CALL.STATUS
  • 重组/重建索引
  • 更新统计信息
相关问题