SQL索引管理器 - 用于SQL Server和Azure上的索引维护的免费GUI工具

我作为SQL Server DBA工作了8年多,管理和优化服务器的性能。在我的空闲时间,我想为宇宙和我的同事做一些有用的事情。这就是我们最终为SQL Server和Azure 提供免费索引维护工具的方法。

理念

每隔一段时间,人们在处理他们的优先事项时,可能就像一个手指式电池 - 一个激励充电只持续一闪,然后一切都消失了。直到最近,我在这一生活观察中也不例外。我经常被想法创造属于我自己的想法所困扰,但优先级从一个变为另一个并且没有完成任何事情。

DevArt开发用于开发和管理SQL Server,MySQL和Oracle数据库的软件,对我的动机和专业成长产生了很大的影响。

在他们来之前,我对创建自己的产品的具体细节知之甚少,但在此过程中,我获得了很多关于SQL Server内部结构的知识。一年多以来,我一直致力于优化产品线中的查询,逐渐开始了解市场上哪些功能比另一种功能更受欢迎。

在某个阶段,制作一个新的利基产品的想法出现在我面前,但由于某些情况,这个想法没有成功。那时,基本上我没有为公司内部的新项目找到足够的资源而不影响核心业务。

在一个崭新的地方工作,并试图自己创建一个项目让我不断妥协。制造一个拥有所有花里胡哨的大产品的最初想法很快就会停止并逐渐转变为一个不同的方向 - 将计划的功能分解为单独的迷你工具并相互独立地实现它们。

因此,SQL Index Manager诞生了,它是SQL Server和Azure的免费索引维护工具。主要想法是将RedGate和Devart公司的商业源码替代品作为基础,并尝试在我自己的项目中改进其功能。

SQL索引管理器 - 用于SQL Server和Azure上的索引维护的免费GUI工具

SQL索引管理器 - 用于SQL Server和Azure上的索引维护的免费GUI工具

履行

口头上说,一切听起来都很简单......只需观看几个激励视频,打开“Rocky Balboa”模式,开始制作一款很酷的产品。但让我们面对音乐,一切都不那么乐观,因为在使用系统表函数时存在许多陷阱,sys.dm_db_index_physical_stats同时,它是唯一可以从中获取有关索引碎片的最新信息的地方。

从开发的最初几天起,就有很好的机会在标准方案中制造沉闷的方式,并复制已经调试过的竞争应用程序的逻辑,同时添加一些自组织。但在分析了元数据的查询后,我想做一些更优化的事情,由于大公司的官僚主义,它们永远不会出现在他们的产品中。

在分析RedGate SQL索引管理器(v1.1.9.1378 - 每个用户155美元)时,您可以看到网站源码使用一种非常简单的方法:使用第一个查询,我们获得用户表和视图的列表,然后第二个,我们返回所选数据库中所有索引的列表。

<span style="color:#000000"><span style="color:#0000ff">SELECT</span> objects.name <span style="color:#0000ff">AS</span> tableOrViewName
     , objects.object_id <span style="color:#0000ff">AS</span> tableOrViewId
     , schemas.name <span style="color:#0000ff">AS</span> schemaName
     , CAST(ISNULL(lobs.NumLobs, <span style="color:#000080">0</span>) <span style="color:#0000ff">AS</span> <span style="color:#0000ff">BIT</span>) <span style="color:#0000ff">AS</span> ContainsLobs
     , o.is_memory_optimized
<span style="color:#0000ff">FROM</span> sys.objects <span style="color:#0000ff">AS</span> objects
<span style="color:#0000ff">JOIN</span> sys.schemas <span style="color:#0000ff">AS</span> schemas <span style="color:#0000ff">ON</span> schemas.schema_id = objects.schema_id
<span style="color:#0000ff">LEFT</span> <span style="color:#0000ff">JOIN</span> (
    <span style="color:#0000ff">SELECT</span> object_id
         , COUNT(*) <span style="color:#0000ff">AS</span> NumLobs
    <span style="color:#0000ff">FROM</span> sys.columns <span style="color:#0000ff">WITH</span> (<span style="color:#0000ff">NOLOCK</span>)
    <span style="color:#0000ff">WHERE</span> system_type_id <span style="color:#0000ff">IN</span> (<span style="color:#000080">34</span>, <span style="color:#000080">35</span>, <span style="color:#000080">99</span>)
        <span style="color:#0000ff">OR</span> max_length = -1
    <span style="color:#0000ff">GROUP</span> <span style="color:#0000ff">BY</span> object_id
) <span style="color:#0000ff">AS</span> lobs <span style="color:#0000ff">ON</span> objects.object_id = lobs.object_id
<span style="color:#0000ff">LEFT</span> <span style="color:#0000ff">JOIN</span> sys.tables <span style="color:#0000ff">AS</span> o <span style="color:#0000ff">ON</span> o.object_id = objects.object_id
<span style="color:#0000ff">WHERE</span> objects.<span style="color:#0000ff">type</span> = <span style="color:#800080">'</span><span style="color:#800080">U'</span>
    <span style="color:#0000ff">OR</span> objects.<span style="color:#0000ff">type</span> = <span style="color:#800080">'</span><span style="color:#800080">V'</span>

<span style="color:#0000ff">SELECT</span> i.object_id <span style="color:#0000ff">AS</span> tableOrViewId
     , i.name <span style="color:#0000ff">AS</span> indexName
     , i.index_id <span style="color:#0000ff">AS</span> indexId
     , i.allow_page_locks <span style="color:#0000ff">AS</span> allowPageLocks
     , p.partition_number <span style="color:#0000ff">AS</span> partitionNumber
     , CAST((c.numPartitions - <span style="color:#000080">1</span>) <span style="color:#0000ff">AS</span> <span style="color:#0000ff">BIT</span>) <span style="color:#0000ff">AS</span> belongsToPartitionedIndex
<span style="color:#0000ff">FROM</span> sys.indexes <span style="color:#0000ff">AS</span> i
<span style="color:#0000ff">JOIN</span> sys.partitions <span style="color:#0000ff">AS</span> p <span style="color:#0000ff">ON</span> p.index_id = i.index_id
                        <span style="color:#0000ff">AND</span> p.object_id = i.object_id
<span style="color:#0000ff">JOIN</span> (
    <span style="color:#0000ff">SELECT</span> COUNT(*) <span style="color:#0000ff">AS</span> numPartitions
         , object_id
         , index_id
    <span style="color:#0000ff">FROM</span> sys.partitions
    <span style="color:#0000ff">GROUP</span> <span style="color:#0000ff">BY</span> object_id
           , index_id
) <span style="color:#0000ff">AS</span> c <span style="color:#0000ff">ON</span> c.index_id = i.index_id
      <span style="color:#0000ff">AND</span> c.object_id = i.object_id
<span style="color:#0000ff">WHERE</span> i.index_id > <span style="color:#000080">0</span> <em><span style="color:#008000">--</span></em><em><span style="color:#008000"> ignore heaps</span></em>
    <span style="color:#0000ff">AND</span> i.is_disabled = <span style="color:#000080">0</span>
    <span style="color:#0000ff">AND</span> i.is_hypothetical = <span style="color:#000080">0</span></span>

接下来,在while每个索引分区的循环中,发送请求以确定其大小和碎片级别。在扫描结束时,客户端上会显示重量小于进入阈值的索引。

<span style="color:#000000"><span style="color:#0000ff">EXEC</span> sp_executesql N<span style="color:#800080">'</span><span style="color:#800080">
SELECT index_id, avg_fragmentation_in_percent, page_count
FROM sys.dm_db_index_physical_stats(@databaseId, @objectId, @indexId, @partitionNr, NUL
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值