排序条件order by id desc后的查询速度为何会变慢??

时间:2022-05-09 02:54:34
Select  ID,Address , AreaDigit , BusinessScope , Corporation , EconomyType , EconomyWay , EmployeeNum  , OrganName , Phone , Postcode , RegisterDate , RegisterMoney 
From Table

--上述查询结果是30万条记录,我做了一下比较:

1.没加排序条件 order by  id desc 的查询速度是:36秒 

2.加排序条件 order by  id desc 后的查询速度是:1分19秒
++++++++++++++++++++++++++++++++++++++++++++++++++++++++
问题一:请问查询速度的差别这是什么原因造成的?
问题二:如过我要按AreaDigit,BusinessScope,EconomyType这三个字段分别来搜索的话,是不要建立索引才能提高查询速度,那么如何建立索引才能真正的提高查询速度。谢谢指点
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++表结构如下:
CREATE TABLE Table

        Address             nvarchar(100) ,
        AreaDigit           nvarchar(100) ,
        BusinessScope       nvarchar(100) ,
        Corporation         nvarchar(100) ,
        EconomyType         nvarchar(100) ,
        EconomyWay          nvarchar(100) ,
        EmployeeNum         nvarchar(100) ,
        ID                  int ,
        OrganName           nvarchar(100) ,
        Phone               nvarchar(100) ,
        Postcode            nvarchar(12) ,
        RegisterDate        nvarchar(100) ,
        RegisterMoney       nvarchar(100)
)
   

21 个解决方案

#1


--order by  id desc  字段要建聚集索引

 --AreaDigit,BusinessScope,EconomyType 建组合索引
试试

--建索引语句:

--建普通索引
create index 索引名称 on 表名(字段)
--建聚集索引
create clustered  index 索引名称 on 表名(字段)
--建非聚集索引
create NONCLUSTERED  index 索引名称 on 表名(字段)

#2


呵呵,因为order by 加了以后要引发全表扫描的原因,正如楼上老兄的说法,要建立上聚集索引

#3


请问 zlp321002() :
在什么条件下建立普通索引?
在什么条件下建立聚集索引?
在什么条件下建立非聚集索引?
谢谢指点

#4


请问 zlp321002() :
在什么条件下建立普通索引?
在什么条件下建立聚集索引?
在什么条件下建立非聚集索引?
谢谢指点

#5


加排序条件 order by  id desc 后的查询,这是按降序来检索。。
不加order by,就符合数据库里面默认是按升序的,如果用了desc,就需要对全表进行扫描,重新排序。。所以所耗的时间就多了。。
这是小弟的理解
不知道是不是这样的原因。。呵呵

#6


搬个凳子坐着听进

#7


在创建聚集索引之前,应先了解您的数据是如何被访问的。可考虑将聚集索引用于: 

包含大量非重复值的列。

使用下列运算符返回一个范围值的查询:BETWEEN、>、>=、< 和 <=。

被连续访问的列。

返回大型结果集的查询。

经常被使用联接或 GROUP BY 子句的查询访问的列;一般来说,这些是外键列。对 ORDER BY 或 GROUP BY 子句中指定的列进行索引,可以使 SQL Server 不必对数据进行排序,因为这些行已经排序。这样可以提高查询性能。

OLTP 类型的应用程序,这些程序要求进行非常快速的单行查找(一般通过主键)。应在主键上创建聚集索引。
 
聚集索引不适用于: 

频繁更改的列 
这将导致整行移动(因为 SQL Server 必须按物理顺序保留行中的数据值)。这一点要特别注意,因为在大数据量事务处理系统中数据是易失的。

宽键 
来自聚集索引的键值由所有非聚集索引作为查找键使用,因此存储在每个非聚集索引的叶条目内。


普通索引可按需创建,但不是索引越多就越好!!

#8


请问各位:
在什么条件下建立普通索引?
在什么条件下建立聚集索引?
在什么条件下建立非聚集索引?
谢谢指点

#9


搜到了这么一段,试问说得有道理不:)
如果column保存了高度相关的数据,并且常常被顺序访问时,最好使用clustered索引,这是因为如果使用clustered索引,SQL Server会在物理上按升序(默认)或者降序重排数据列,这样就可以迅速的找到被查询的数据。同样,在搜寻控制在一定范围内的情况下,对这些 column也最好使用clustered索引。这是因为由于物理上重排数据,每个表格上只有一个clustered索引。 与上面情况相反,如果columns包含的数据相关性较差,你可以使用nonculstered索引。你可以在一个表格中使用高达249个nonclustered索引——尽管我想象不出实际应用场合会用的上这么多索引。

当表格使用主关键字(primary keys),默认情况下SQL Server会自动对包含该关键字的column(s)建立一个独有的cluster索引。很显然,对这些column(s)建立独有索引意味着主关键字的唯一性。当建立外关键字(foreign key)关系时,如果你打算频繁使用它,那么在外关键字cloumn上建立nonclustered索引不失为一个好的方法。如果表格有clustered索引,那么它用一个链表来维护数据页之间的关系。相反,如果表格没有clustered索引,SQL Server将在一个堆栈中保存数据页。

#10


如果记录没必有排序,最好不好排,
排序时数据库需要逐条记录比较,是最费时间的.

#11


学习

#12


在什么条件下建立普通索引?在什么条件下建立聚集索引?在什么条件下建立非聚集索引?
----------------------------
你再问这个问题的时候要先搞清楚什么叫普通索引什么叫聚集索引

每个索引是一个B+树 不断往下扩展(繁衍)以容纳更多的记录 (好比一棵大树要结满更多的果实需要茂密的枝节) 索引从SQL某个版本之后于表页在物理位置上独立出来 为的是更好的读写性能即它占用索引页
对于普通索引(非聚集索引)来说 这个B+树的最底层指向表页面的物理位置 它不对这条记录作维护和物理位置上的调整 对于聚集索引来说 B+树包括物理页面 在表被更改之后 除了新建索引项 其auto stats会自动维护底层节点的排序从而加快查询效率 保证物理上的连续性

一句话 聚集索引末节点包括数据页面而非聚集索引不包括
结合这个原理 你也可以了解索引的填充率的概念 0%会造成大量索引页 造成索引扫描速度的降低 100%会在进行表插入时候性能的降低 因为需要生成额外的索引页

后面的补充

#13


对排序的栏位建聚集索引。

#14


问题1 
order by  id desc 
加了order by这样的语句SQL Server会在tempdb里将取得的数据排个序,加个聚集索引能有效的提高速度的,因为,读有聚集索引的字段获得的数据本身就是排好序的。

问题2
加上索引无疑可以提高检索速度,但如何加索引没有什么特别的规范,依托于实际应用。

#15


对于上述表我要实现三种查询并排序
SELECT * FROM SHANGHAI where Postcode    = '200000' ordey by id desc
SELECT * FROM SHANGHAI where EconomyWay  = 'xxxxxx' ordey by id desc
SELECT * FROM SHANGHAI where EconomyType = 'yyyyyy' ordey by id desc
于是我这样来建立索引大家觉得是否合理:
 CREATE  CLUSTERED  INDEX [IX_ShangHai] ON [dbo].[ShangHai]([Postcode], [EconomyWay], [EconomyType]) ON [PRIMARY]
GO

ALTER TABLE [dbo].[ShangHai] WITH NOCHECK ADD 
CONSTRAINT [PK_ShangHai] PRIMARY KEY  NONCLUSTERED 
(
[ID] DESC 
)  ON [PRIMARY] 
GO
谢谢指点!

#16


簇集索引好像是要保证([Postcode], [EconomyWay])的唯一性
然后你对这章表不能频繁插入/更新数据

#17


我只是要对Postcode, EconomyWay,EconomyType这三个字段进行频繁的查询并按ID排序操作

#18


学习了,但还是搞不懂那么多索引?

#19


那你就对这三个字段加个聚集索引 并观察一下性能

#20


select * from shanghai
1.没加索引前的查询时间:36秒 
select * from shanghai
2.加索引后的查询时间:9秒 
select * from shanghai:)好象快了很多


3.没加索引+排序条件 order by  id desc 后的查询速度是:1分19秒
select * from shanghai order by  id desc
4.加索引后+排序条件 order by  id desc 后的查询速度是:56秒 
select * from shanghai order by  id desc
:)好象没快多少


#21


mark

#1


--order by  id desc  字段要建聚集索引

 --AreaDigit,BusinessScope,EconomyType 建组合索引
试试

--建索引语句:

--建普通索引
create index 索引名称 on 表名(字段)
--建聚集索引
create clustered  index 索引名称 on 表名(字段)
--建非聚集索引
create NONCLUSTERED  index 索引名称 on 表名(字段)

#2


呵呵,因为order by 加了以后要引发全表扫描的原因,正如楼上老兄的说法,要建立上聚集索引

#3


请问 zlp321002() :
在什么条件下建立普通索引?
在什么条件下建立聚集索引?
在什么条件下建立非聚集索引?
谢谢指点

#4


请问 zlp321002() :
在什么条件下建立普通索引?
在什么条件下建立聚集索引?
在什么条件下建立非聚集索引?
谢谢指点

#5


加排序条件 order by  id desc 后的查询,这是按降序来检索。。
不加order by,就符合数据库里面默认是按升序的,如果用了desc,就需要对全表进行扫描,重新排序。。所以所耗的时间就多了。。
这是小弟的理解
不知道是不是这样的原因。。呵呵

#6


搬个凳子坐着听进

#7


在创建聚集索引之前,应先了解您的数据是如何被访问的。可考虑将聚集索引用于: 

包含大量非重复值的列。

使用下列运算符返回一个范围值的查询:BETWEEN、>、>=、< 和 <=。

被连续访问的列。

返回大型结果集的查询。

经常被使用联接或 GROUP BY 子句的查询访问的列;一般来说,这些是外键列。对 ORDER BY 或 GROUP BY 子句中指定的列进行索引,可以使 SQL Server 不必对数据进行排序,因为这些行已经排序。这样可以提高查询性能。

OLTP 类型的应用程序,这些程序要求进行非常快速的单行查找(一般通过主键)。应在主键上创建聚集索引。
 
聚集索引不适用于: 

频繁更改的列 
这将导致整行移动(因为 SQL Server 必须按物理顺序保留行中的数据值)。这一点要特别注意,因为在大数据量事务处理系统中数据是易失的。

宽键 
来自聚集索引的键值由所有非聚集索引作为查找键使用,因此存储在每个非聚集索引的叶条目内。


普通索引可按需创建,但不是索引越多就越好!!

#8


请问各位:
在什么条件下建立普通索引?
在什么条件下建立聚集索引?
在什么条件下建立非聚集索引?
谢谢指点

#9


搜到了这么一段,试问说得有道理不:)
如果column保存了高度相关的数据,并且常常被顺序访问时,最好使用clustered索引,这是因为如果使用clustered索引,SQL Server会在物理上按升序(默认)或者降序重排数据列,这样就可以迅速的找到被查询的数据。同样,在搜寻控制在一定范围内的情况下,对这些 column也最好使用clustered索引。这是因为由于物理上重排数据,每个表格上只有一个clustered索引。 与上面情况相反,如果columns包含的数据相关性较差,你可以使用nonculstered索引。你可以在一个表格中使用高达249个nonclustered索引——尽管我想象不出实际应用场合会用的上这么多索引。

当表格使用主关键字(primary keys),默认情况下SQL Server会自动对包含该关键字的column(s)建立一个独有的cluster索引。很显然,对这些column(s)建立独有索引意味着主关键字的唯一性。当建立外关键字(foreign key)关系时,如果你打算频繁使用它,那么在外关键字cloumn上建立nonclustered索引不失为一个好的方法。如果表格有clustered索引,那么它用一个链表来维护数据页之间的关系。相反,如果表格没有clustered索引,SQL Server将在一个堆栈中保存数据页。

#10


如果记录没必有排序,最好不好排,
排序时数据库需要逐条记录比较,是最费时间的.

#11


学习

#12


在什么条件下建立普通索引?在什么条件下建立聚集索引?在什么条件下建立非聚集索引?
----------------------------
你再问这个问题的时候要先搞清楚什么叫普通索引什么叫聚集索引

每个索引是一个B+树 不断往下扩展(繁衍)以容纳更多的记录 (好比一棵大树要结满更多的果实需要茂密的枝节) 索引从SQL某个版本之后于表页在物理位置上独立出来 为的是更好的读写性能即它占用索引页
对于普通索引(非聚集索引)来说 这个B+树的最底层指向表页面的物理位置 它不对这条记录作维护和物理位置上的调整 对于聚集索引来说 B+树包括物理页面 在表被更改之后 除了新建索引项 其auto stats会自动维护底层节点的排序从而加快查询效率 保证物理上的连续性

一句话 聚集索引末节点包括数据页面而非聚集索引不包括
结合这个原理 你也可以了解索引的填充率的概念 0%会造成大量索引页 造成索引扫描速度的降低 100%会在进行表插入时候性能的降低 因为需要生成额外的索引页

后面的补充

#13


对排序的栏位建聚集索引。

#14


问题1 
order by  id desc 
加了order by这样的语句SQL Server会在tempdb里将取得的数据排个序,加个聚集索引能有效的提高速度的,因为,读有聚集索引的字段获得的数据本身就是排好序的。

问题2
加上索引无疑可以提高检索速度,但如何加索引没有什么特别的规范,依托于实际应用。

#15


对于上述表我要实现三种查询并排序
SELECT * FROM SHANGHAI where Postcode    = '200000' ordey by id desc
SELECT * FROM SHANGHAI where EconomyWay  = 'xxxxxx' ordey by id desc
SELECT * FROM SHANGHAI where EconomyType = 'yyyyyy' ordey by id desc
于是我这样来建立索引大家觉得是否合理:
 CREATE  CLUSTERED  INDEX [IX_ShangHai] ON [dbo].[ShangHai]([Postcode], [EconomyWay], [EconomyType]) ON [PRIMARY]
GO

ALTER TABLE [dbo].[ShangHai] WITH NOCHECK ADD 
CONSTRAINT [PK_ShangHai] PRIMARY KEY  NONCLUSTERED 
(
[ID] DESC 
)  ON [PRIMARY] 
GO
谢谢指点!

#16


簇集索引好像是要保证([Postcode], [EconomyWay])的唯一性
然后你对这章表不能频繁插入/更新数据

#17


我只是要对Postcode, EconomyWay,EconomyType这三个字段进行频繁的查询并按ID排序操作

#18


学习了,但还是搞不懂那么多索引?

#19


那你就对这三个字段加个聚集索引 并观察一下性能

#20


select * from shanghai
1.没加索引前的查询时间:36秒 
select * from shanghai
2.加索引后的查询时间:9秒 
select * from shanghai:)好象快了很多


3.没加索引+排序条件 order by  id desc 后的查询速度是:1分19秒
select * from shanghai order by  id desc
4.加索引后+排序条件 order by  id desc 后的查询速度是:56秒 
select * from shanghai order by  id desc
:)好象没快多少


#21


mark