我的表结构如下
set statistics io on
SELECT
COUNT(featureid), featureid
FROM
AIRQUALITYTS2
WHERE
FeatureID LIKE 'AS%'
AND ParameterID = 'AP2'
AND YEAR(MeasurementDateTime) = 2015
GROUP BY
FeatureID
ORDER BY
FeatureID
执行此查询时:
CREATE NONCLUSTERED INDEX non_fidpidmdate
ON [dbo].[AIRQUALITYTS2] ([ParameterID], [FeatureID])
INCLUDE ([MeasurementDateTime])
我看到逻辑记录 101871 ,查询执行计划是
但是当我在这个表上添加非聚集索引
时MeasurementDateTime >= '2004-01-01 00:00:00'
and MeasurementDateTime <= '2004-12-31 00:00:00'
当我执行相同的查询时,我看到逻辑记录只读取 4636 ,速度非常快,查询执行计划是
问题1:第二次查询中的逻辑记录较少。
问题2:为什么第一个查询使用第一个图像中显示的聚簇索引扫描虽然它在featureid,ParameterID和MeasurementDateTime上有聚簇索引,但在添加非聚簇索引后它使用索引寻找(非聚集)第二张图像,如图像所示
注意:我已将where子句更改为
@media screen and (max-width: 767px) {
.container {
width: 100%;
}
.logo {
background-position: 50% 30px;
}
.banner {
height: 500px;
}
.banner h1 {
margin-top: 0px;
}
.title {
background-color: #d44137;
width: 100%;
margin: 0;
}
.pricing h2 {
display: none;
}
.pricing {
width: 100%;
}
.pricing p {
width: 95%;
}
.pricing-1 {
margin-left: 0;
}
.pricing-1 p {
margin-left: 0;
}
.content {
width: 100%;
}
.sidebar {
width: 100%;
}
.testimonials {
width: 90%;
float: left;
margin: 0;
padding: 10px 5% 10px 5%;
}
.records {
width: 90%;
float: left;
padding: 10px 0 10px 5%;
}
.info {
width: 90%;
float: left;
text-align: justify;
padding: 10px 0 10px 5%;
}
.info img {
display: none;
}
.company {
width: 90%;
float: left;
padding: 10px 5% 20px 5%;
}
.video {
width: 90%;
float: left;
margin-left: 5%;
padding-bottom: 20px;
}
form {
width: 90%;
margin: 0 5% 30px 5%;
}
.map {
width: 90%;
margin: 0 5% 30px 5%;
}
.contact h1 {
margin-left: 5%;
}
.footer {
height: 70px;
}
.copyright {
font-size: 9pt;
text-align: center;
}
.social {
display: none;
}
}
让它变得可靠,但结果仍然相同。
答案 0 :(得分:2)
对于问题1:由于您的索引涵盖(它包含查询要检索的所有数据以及查询和排序的需要),因此查询可以完全针对索引运行(和它的数据页面并使用搜索,与扫描整个表格(聚集索引扫描 =表扫描)相比,显然从磁盘上加载的页数要少得多数据
不确定你对问题#2的意思....
答案 1 :(得分:1)
CREATE TABLE
的原始PRIMARY KEY CLUSTERED
中,它按照中聚类(存储)的顺序指定要聚类的列。 [FeatureID] [ParameterID] [MeasurementDateTime]
如果您使用包含特定WHERE
的{{1}}子句运行查询,那么它将能够FeatureID
到索引的该部分。
但是你没有在查询中这样做。
您已使用seek
查询引擎无法搜索,因为带有尾随通配符WHERE FeatureID LIKE 'AS%' ...
的{{1}}表示必须扫描以字母LIKE
开头的所有FeatureID,然后才能扫描每个树中的节点查看是否存在与%
匹配的记录。
AS
当您运行相同的查询时,它可以ParameterID = 'AP2' AND YEAR(MeasurementDateTime) = 2015
,因为您已在[ParameterID]
[FeatureID]
子句中指定了精确的seek
。
订购很重要! SQL索引是 sortof B-Tree数据结构,您无法在不创建多个索引的情况下以不同的顺序物理存储它们(或遍历它们)。创建太多的索引对于数据库来说可能是一个太多的开销,因此创建一个可以帮助大多数查询但不会创建太多的查询。这主要涉及了解经常针对您的数据库运行哪种查询并进行相应调整。