【发布时间】:2014-06-11 11:35:18
【问题描述】:
关于 SQL Server 和索引,我有一些不明白的地方。昨晚我正在处理一张包含 100M 行的表。我创建了以下索引:
CREATE NONCLUSTERED INDEX [x_acct_x_date_x_type] ON [mail_master]
(
[letter_acct] ASC,
[letter_date] ASC,
[letter_type] ASC
)
我通常不会创建涉及 3 列的索引。我从这个表中选择语句用于生产需要 6 秒,其中一个 WHERE 子句利用了这 3 个字段中的每一个。我将我的代码和索引推荐给了一位有点老派的同事,以获取有关优化的建议,他建议放弃 letter_type。然后,我们运行相同的代码,该代码需要 6 秒,替换的索引应用于两个字段,现在需要 0 秒。
我问他为什么,除了我的索引的静态数据大于修改后的索引之外,他无法真正给我答案。他是绝对正确的,但我真的不明白为什么现在会是 0 秒。
谁能告诉我为什么会这样?提前谢谢你。
这里是 CREATE TABLE 语句:
CREATE TABLE [mail_master](
[client_acct] [varchar](4) NULL,
[letter_acct] [varchar](11) NULL,
[letter_date] [datetime] NULL,
[letter_type] [varchar](25) NULL,
[letter_balance] [money] NULL,
[special] [varchar](35) NULL,
[call] [datetime] NULL,
[mail_return] [varchar](1) NULL,
[payment_date] [datetime] NULL,
[post_date] [datetime] NULL,
[promise] [datetime] NULL,
[age] [int] NULL
) ON [PRIMARY]
这里是有问题的 tsql 代码:
DECLARE @ClientTable AS TABLE (
client_acct VARCHAR(4),
client_name VARCHAR(40),
grade VARCHAR(2),
acct_type VARCHAR(20)
)
INSERT INTO @ClientTable (
client_acct,
client_name,
grade,
acct_type
)
SELECT client_acct_info_t.client_acct,
client_name,
grade,
acct_type
FROM client_acct_info_t,
client_master_t
WHERE client_master_t.client_acct = client_acct_info_t.client_acct
AND acct_status = 'A'
SELECT mail_master.client_acct AS 'Client #',
client_name AS 'Client Name',
COUNT(*),
SUM(total_payments) AS 'Total Payments',
SUM(sum_payments) AS 'Total Payment Dollars'
FROM mail_master,
@ClientTable AS ClientTable
WHERE mail_master.client_acct = ClientTable.client_acct
AND letter_date >= '03/01/2014'
AND letter_date <= '03/25/2014'
AND letter_type = 'PRECOLLECT'
AND letter_balance >= 100
AND letter_balance <= 1000
GROUP BY mail_master.client_acct,
client_name
【问题讨论】:
-
第一种可能是你在比较苹果和橙子,因为你需要在没有缓存的情况下比较结果。更重要的是,我们不能在没有看到查询的情况下评论索引的使用。请编辑问题以包含查询。
-
where子句是列
letter_acct引用的哪里? -
好问题,在这个特定的查询中,我没有使用 letter_acct 列。
标签: sql sql-server tsql optimization indexing