Sql server 创建索引后,只有查询后重建才会生效,不知为啥?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Sql server 创建索引后,只有查询后重建才会生效,不知为啥?相关的知识,希望对你有一定的参考价值。
对Sql Server数据库表创建非聚簇索引后,直接查询速度没有变化,此时将索引删掉,重新创建后,索引才起作用,速度才很快。不知背后的原因是什么? 另,索引生效后,数据库重启后就又无效了。 有什么办法能解决? 想在创建索引后,一直生效,数据库重启或其他方式均不受影响。
应该和设置当前索引有关。例如ADO借口中就有这类的参数。Foxpro中有setindex
to等语句。 参考技术A 这个是立即生效的,,,,
当然你如果查询情况也会判断会不会使用索引
SQL Server 索引重建手册
注意:
索引重建前建议把数据库切换为完整模式,否则索引复制会在数据文件中进行,导致数据文件很大,而数据文件的收缩比日志文件的收缩要困难的多,且会对业务造成影响。
步骤一:
查询索引碎片,脚本如下,库比较大时执行时间会很长,虽然对数据库影响不大,依然建议在非高峰时段执行。(执行之前请先选定要查询碎片的数据库)
Declare @dbid int
Select @dbid=DB_ID()
SELECT DB_NAME(ps.database_id) AS [Database Name], OBJECT_NAME(ps.OBJECT_ID) AS [Object Name],
i.name AS [Index Name], ps.index_id, ps.index_type_desc, ps.avg_fragmentation_in_percent,
ps.fragment_count, ps.page_count, i.fill_factor, i.has_filter, i.filter_definition
FROM sys.dm_db_index_physical_stats(@dbid,NULL, NULL, NULL,null) AS ps
INNER JOIN sys.indexes AS i WITH (NOLOCK)
ON ps.[object_id] = i.[object_id]
AND ps.index_id = i.index_id
WHERE ps.database_id = DB_ID()
AND ps.index_type_desc <> \'HEAP\'
AND ps.page_count > 2500
ORDER BY ps.avg_fragmentation_in_percent DESC OPTION (RECOMPILE);
步骤二:
筛选需要进行索引重建的表,举例如下:
一般来说,avg_fragmentation_in_percent大于60%就可以考虑重建了,因此本例中前10个索引都需要重建。其中index_id为1的表示是聚集索引(主键索引)。
步骤三:
!!!重要警告:操作前先备份全库,留后手永远是对自己和企业最大的负责。
索引重建的方式,我们一般采用在线重建的方式(SQL Server 2005之前的版本不支持),因此语句如下:
alter index index_name
on table_name
rebuild
with(online = on ,sort_in_tempDB = on , maxdop = 最大并行度);
go
在这里最大并行度应当选择操作系统CPU核数的80%为宜。
此外索引重建应当遵循以下原则:
- 为避免空间使用过多,应当对索引进行依次重建,不建议使用alter index all on table_name...的语句。
- 如果一个表有多个索引需要重建,则重建的顺序必须为:先重建聚集索引(即主键索引),再重建非聚集索引。
步骤四:
在在线重建索引的过程中,需要观察索引重建的进度,但是online索引重建的进度并不会在sys.dm_exec_requests中显示,因此微软提供了另一种查看完成进度的方式,具体如下:
在sql profiler的Progress Report中,可以监视Online Index Operation的情况。
其中BigintData1表示已经完成的在线重建记录数,BigData2表示当前线程的序列号,只要把所有进程的max(bigdata1)之和与和表的总行数比较一下就可以大致知道目前的进度了。
注意由于每个任务分配的行数并不均匀,所以估算的结果不是很精确,不过一般不会太离谱。
以上是关于Sql server 创建索引后,只有查询后重建才会生效,不知为啥?的主要内容,如果未能解决你的问题,请参考以下文章