Questions tagged «index»

一种数据库结构,可以以磁盘空间为代价提高查询速度,并降低插入/更新的速度。它存储一个或多个排序的列的副本,但以不同的方式构造数据以允许更快地访问。

5
当强制实施IsDeleted(软删除)时,合适的索引体系结构是什么?
当前,我们有一个功能齐全的现有数据库和应用程序。我目前无法更改架构。今天,数据库中的每个表都有一个“ IsDeleted” NOT NULL BIT字段,默认值为“ 0”。当应用程序“删除”数据时,它只是将IsDeleted标志更新为1。 我无法理解的是每个表的索引应如何构造。现在,每个查询/联接/等总是执行IsDeleted检查。这是我们开发人员必须遵循的标准。话虽这么说,我试图确定是否需要更改每个表上的所有群集主键索引,以包括主键和IsDeleted BIT字段。另外,由于每个查询/加入/等。必须执行IsDeleted检查,是否适当地假设每个单索引(以及非聚簇索引)都应将IsDeleted字段包括为索引的第一个字段? 我还有一个问题是关于过滤索引的。我知道我可以在诸如“ WHERE IsDeleted = 0”之类的索引上放置过滤器,以减少索引的大小。但是,由于每个联接/查询都必须实现IsDeleted检查,这是否会阻止使用过滤后的索引(因为联接/查询中使用了IsDeleted列)? 请记住,我没有能力更改IsDeleted方法。

3
索引对更新列不在索引中的更新语句的影响
我经常看到人们说索引变慢update,delete并且insert。这用作一揽子声明,就好像它是绝对的一样。 在调整数据库以提高性能的同时,我不断遇到这种情况,这种情况似乎在逻辑上对我来说与该规则相矛盾,而且我在任何地方都找不到其他方式可以说或解释的人。 在SQL Server中,并且我相信/假定将使用大多数其他DBMS,您的索引是根据您指定的特定列创建的。插入和删除将始终影响整个行,因此没有办法不会影响索引,但是更新似乎更加独特,它们可以专门影响某些列。 如果我有未包含在任何索引中的列并更新了它们,它们是否会因为我在该表中的其他列上有索引而放慢了速度? 例如,在我的User表中,我有一个或两个索引,主键是Identity / Auto Increment列,外键列上可能还有另一个。 如果我更新没有索引直接在其上的列(例如说他们的电话号码或地址),由于在任何一种情况下我在该表的其他列上都有索引,此更新是否会变慢?我要更新的列不在索引中,因此从逻辑上讲,不应更新索引,不是吗?如果有的话,如果我使用WHERE子句中的索引,我认为它们会加快速度。

1
删除未使用的索引-评估意外的危险
根据DMV统计数据,我们有一个非常大的数据库,其中包含数百个未使用的索引,自从服务器在7月最后一次重新启动以来,该索引一直在累积。我们的一名DBA做出了以下警告性声明,这对我来说没有意义: 在删除索引之前,我们需要确定它是否不执行唯一性约束,因为查询优化器可能需要该索引存在。 每当创建索引时,都会在SQL Server中创建与该索引相关的统计信息。查询可能未使用索引,但可能正在使用其统计信息。因此,我们可能会遇到这样的情况:在删除索引之后,特定的查询性能会变得很差。SQL Server不保留统计信息的使用情况统计信息。尽管我们在数据库上启用了“自动创建统计信息”功能,但是我不知道在查询优化器创建丢失的统计信息之前必须在内部满足哪些所有参数。 关于#1,在我看来,SQL Server实际上会在完成插入/更新之前对索引进行一次搜索以确定唯一性,因此,该索引不会显示为未使用。 关于#2,这真的有可能吗? 顺便说一句,当我说不使用索引时,我的意思是没有搜寻也没有扫描。
16 sql-server  index 

3
在SAN环境中对SQL索引进行碎片整理有什么好处?
我们的SQL服务器位于SAN上。它包含数十个OLTP数据库,其中一些数据库包含100万条以上的记录。 我们每周运行Ola Hallengren的索引维护脚本,并且每次运行几个小时。根据碎片阈值,脚本将重新组织索引或为索引重新编制索引。我们已经观察到,在重新索引期间,日志文件会变得很大,这会导致日志传送过程中带宽的过度消耗。 然后是Brent Ozar的一篇文章,他说不再停止担心SQL索引: 您的硬盘驱动器与其他同时共享驱动器请求的服务器共享,因此驱动器将始终在各处跳跃以获取数据。整理索引碎片只是毫无意义的繁忙工作。 谷歌搜索这个问题会导致意见分歧,其中大多数观点似乎太简短或太弱。我们的暂定计划是调整维护脚本中的碎片阈值,以使其重新组织的频率比重新编制索引的频率高得多。 最终裁决是什么?考虑到每周运行维护工作所带来的负担,是否值得对SAN上的SQL索引进行碎片整理?

2
简单联接中未使用的主键索引
我有以下表和索引定义: CREATE TABLE munkalap ( munkalap_id serial PRIMARY KEY, ... ); CREATE TABLE munkalap_lepes ( munkalap_lepes_id serial PRIMARY KEY, munkalap_id integer REFERENCES munkalap (munkalap_id), ... ); CREATE INDEX idx_munkalap_lepes_munkalap_id ON munkalap_lepes (munkalap_id); 为什么在以下查询中不使用munkalap_id上的索引? EXPLAIN ANALYZE SELECT ml.* FROM munkalap m JOIN munkalap_lepes ml USING (munkalap_id); QUERY PLAN Hash Join (cost=119.17..2050.88 …

1
数据库如何存储可变长度字段的索引键值(在磁盘上)?
语境 这个问题与SQL和NoSQL数据库系统中索引的低级实现细节有关。索引的实际结构(B +树,哈希,SSTable等)无关紧要,因为该问题专门涉及存储在任何这些实现​​的单个节点内的键。 背景 在SQL(如MySQL的)和NoSQL(CouchDB的,MongoDB的,等等)数据库,如果您在列或数据的JSON文档字段建立索引,你实际上是导致数据库做的就是创建本质上所有的排序列表这些值以及与该值有关的记录所在的主数据文件中的文件偏移量。 (为简单起见,我可能会手动放弃特定展示的其他深奥细节) 简单经典SQL示例 考虑一个标准的SQL表,该表具有一个简单的32位int主键,我们可以在该主键上创建索引,我们最终将获得一个排序后的整数键的索引在磁盘上的索引,并与数据文件中的64位偏移量相关联,其中记录的生命,例如: id | offset -------------- 1 | 1375 2 | 1413 3 | 1786 索引中键的磁盘上表示形式类似于以下内容: [4-bytes][8-bytes] --> 12 bytes for each indexed value 坚持使用文件系统和数据库系统优化磁盘I / O的标准经验法则,假设您将密钥存储在磁盘上的4KB块中,这意味着: 4096 bytes / 12 bytes per key = 341 keys per block 忽略索引的整体结构(B +树,哈希,排序列表等),我们一次将341个键的块读写到内存中,然后根据需要返回到磁盘。 查询范例 使用上一部分中的信息,假设有一个查询“ id …
16 mongodb  index  nosql  couchdb 

5
什么时候应该将非聚集索引存储在单独的文件组中?
我听说将索引存储在不同的文件组和驱动器上可以提高数据库的性能,因为驱动器不必在索引和索引所引用的数据之间来回移动。我也听说这是一个神话。 何时建议将非聚集索引存储在单独的文件组和驱动器上?什么性能/分析器证据会导致我得出该结论?硬件在决策中是否起作用(是否在单个驱动器上使用RAID / SAN)?
16 sql-server  index 

2
SQL Server 2008-分区和聚集索引
因此,请允许我说我对数据库的设计没有完全控制权,因此,对于本场景而言,无法更改当前系统的许多方面。 关于我们应该如何重新考虑设计方面的评论可能是正确的,但无济于事:) 我有一个很大的表,大约150个字段宽,大约600m行,它驱动着大量的进程。这是在数据仓库的情况下,因此我们在计划的加载过程之外没有任何更新/插入,因此它的索引很高。 已做出尝试对该表进行分区的决定,并且我对索引已分区表有些担忧。我没有分区方面的经验,因此不胜感激任何输入或链接。我在BOL或msdn上找不到具体的位置。 目前我们群集上一个领域,我们称之为IncidentKey这是一个varchar(50),而不是唯一的-我们可以1-100记录与同一之间有IK(没有意见,请)。我们经常会在旧IncidentKey记录上获取新数据,因此也不是连续的。 我了解我需要IncidentDate在群集索引键中包含分区字段,以使分区正常工作。我在想IncidentKey, IncidentDate。 问题是,如果“新”分区中的记录应该在聚簇索引中“旧”分区中的记录之前,则聚簇索引的机制将如何在分区表的2部分键上工作? 例如,我有5条记录: IncidentKey Date ABC123 1/1/2010 ABC123 7/1/2010 ABC123 1/1/2011 XYZ999 1/1/2010 XYZ999 7/1/2010 如果我得到一条新记录,ABC123, 2/1/2011它将需要在聚集索引BEFORE中 XYZ999, 1/1/2010。这是如何运作的? 我假设使用碎片和指针,但是找不到具有双部分键的分区表上非分区聚簇索引的物理存储和配置的任何信息。

1
多租户SQL Server数据库中的复合主键
我正在使用ASP Web API,实体框架和SQL Server / Azure数据库构建多租户应用程序(单个数据库,单个架构)。此应用将由1000-5000个客户使用。所有表都将具有TenantId(Guid / UNIQUEIDENTIFIER)字段。现在,我使用的是ID(Guid)的单字段主键。但是,仅使用Id字段,我就必须检查用户提供的数据是否来自/正确的租户。例如,我有一个SalesOrder包含CustomerId字段的表。每次用户发布/更新销售订单时,我都必须检查是否CustomerId来自同一租户。情况变得更糟,因为每个租户可能都有多个出口。然后我要检查TenantId和OutletId。这确实是维护的噩梦,并且对性能不利。 我正在考虑将一起添加TenantId到主键中Id。并可能也添加OutletId。所以在主键SalesOrder表将是:Id,TenantId,和OutletId。这种方法的缺点是什么?使用复合键会严重损害性能吗?复合键顺序重要吗?我的问题有更好的解决方案吗?

5
尝试回收未使用的空间会导致已用空间在SQL Server中显着增加
我在生产数据库中有一个表,该表的大小为525 GB,其中383 GB未使用: 我想回收一些空间,但是在弄乱生产数据库之前,我正在用较少数据的测试数据库中的同一表上测试一些策略。该表有一个类似的问题: 有关表的一些信息: 填充因子设置为0 大约有30列 列之一是图像类型的LOB,它存储的文件大小从几KB到几百MB不等 该表没有任何与之相关的假设索引 服务器正在运行SQL Server 2017(RTM-GDR)(KB4505224)-14.0.2027.2(X64)。数据库正在使用SIMPLE恢复模型。 我尝试过的一些事情: 重建索引: ALTER INDEX ALL ON dbo.MyTable REBUILD。这产生的影响可以忽略不计。 重组索引:ALTER INDEX ALL ON dbo.MyTable REORGANIZE WITH(LOB_COMPACTION = ON)。这产生的影响可以忽略不计。 将LOB列复制到另一个表,删除该列,重新创建该列,然后将数据复制回(如本文章中概述的:释放未使用的空间SQL Server表)。这减少了未使用的空间,但似乎只是将其转换为已用空间: 使用了bcp实用程序来导出表,截断表并重新加载表(如本文所述:如何为表释放未使用的空间)。这也减少了未使用的空间,并将使用的空间增加到与上述图像相似的程度。 即使不建议这样做,我也尝试了DBCC SHRINKFILE和DBCC SHRINKDATABASE命令,但是它们对未使用的空间没有任何影响。 跑步 DBCC CLEANTABLE('myDB', 'dbo.myTable')并没有改变 在保持图像和文本数据类型以及将数据类型更改为varbinary(max)和varchar(max)之后,我都尝试了上述所有方法。 我尝试将数据导入到新数据库中的新表中,这也仅将未使用的空间转换为已用空间。我在这篇文章中概述了这种尝试的细节。 如果我期望这些结果,我不想在生产数据库上进行这些尝试,因此: 为什么将其中一些尝试之后的未使用空间仅转换为已用空间?我觉得我不太了解幕后发生的事情。 我还能做些其他事情来减少未使用的空间而不增加已使用的空间吗? 编辑:这是表的磁盘使用情况报告和脚本: SET ANSI_NULLS ON GO SET …

1
缺少多个索引的执行计划
如果使用“包含实际执行计划”运行查询,则该计划还将建议缺少的索引。索引详细信息MissingIndexes位于XML的内部标记中。计划中包含多个索引建议时会出现这种情况吗?我尝试了不同的sql查询,但是无法提供任何生成两个或多个缺失索引的查询。

2
不可搜索的持久化计算列上的索引
我有Address一个名为的表,该表具有一个称为的持久计算列Hashkey。该列是确定性的,但不精确。它具有不可搜索的唯一索引。如果运行此查询,则返回主键: SELECT @ADDRESSID= ISNULL(AddressId,0) FROM dbo.[Address] WHERE HashKey = @HashKey 我得到这个计划: 如果我强制索引,我会得到更糟糕的计划: 如果我尝试同时使用索引和查找,则会收到错误消息: 由于此查询中定义的提示,查询处理器无法生成查询计划。重新提交查询而不指定任何提示,也无需使用SET FORCEPLAN 这仅仅是因为它不精确吗?我以为如果坚持下去没关系吗? 有没有一种方法可以使该索引可查询而不将其设为非计算列? 有人在此链接到任何信息吗? 我无法发布实际的表创建,但是这是一个具有相同问题的测试表: drop TABLE [dbo].[Test] CREATE TABLE [dbo].[Test] ( [test] [VARCHAR](100) NULL, [TestGeocode] [geography] NULL, [Hashkey] AS CAST( ( hashbytes ('SHA', ( RIGHT(REPLICATE(' ', (100)) + isnull([test], ''), ( 100 )) ) + …

3
具有WHERE条件和GROUP BY的SQL查询的索引
我试图确定要用于带有WHERE条件的SQL查询的索引,GROUP BY而当前正在运行的索引非常慢。 我的查询: SELECT group_id FROM counter WHERE ts between timestamp '2014-03-02 00:00:00.0' and timestamp '2014-03-05 12:00:00.0' GROUP BY group_id 该表当前有32.000.000行。当我增加时间范围时,查询的执行时间会增加很多。 有问题的表如下所示: CREATE TABLE counter ( id bigserial PRIMARY KEY , ts timestamp NOT NULL , group_id bigint NOT NULL ); 我目前有以下索引,但是性能仍然很慢: CREATE INDEX ts_index ON counter USING btree (ts); …

2
索引是否必须覆盖所有选定的列才能用于ORDER BY?
在SO上,最近有人问为什么不使用ORDER BY? 这种情况涉及MySQL中的一个简单的InnoDB表,该表包含三列和1万行。其中一列(整数)被索引了,OP试图检索按该列排序的整个表: SELECT * FROM person ORDER BY age 他附加了EXPLAIN输出,该输出显示此查询是使用filesort(而不是索引)解决的,并询问为什么会这样。 尽管有提示 FORCE INDEX FOR ORDER BY (age) 导致使用索引的提示,但有人回答(带有支持的注释/来自他人的评论)说,仅当从索引中读取所有选定的列时,索引才用于排序(即通常由Using index该Extra列中的指示)的EXPLAIN输出)。稍后给出了一个解释,即遍历索引然后从表中获取列会导致随机I / O,MySQL认为它比a更昂贵filesort。 这似乎是在关于ORDER BY优化的手册一章中碰到的,它不仅传达出强烈的印象,即ORDER BY从索引满足比执行其他排序更可取(实际上,它filesort是quicksort和mergesort的组合,因此 必须具有下限;虽然应该按顺序遍历索引并查找表,所以这很有意义),但它也忽略了此所谓的“优化”,同时还指出:Ω(nlog n)O(n) 以下查询使用索引来解析ORDER BY零件: SELECT * FROM t1 ORDER BY key_part1,key_part2,... ; 就我的阅读而言,在这种情况下就是这种情况(但没有明确提示就没有使用索引)。 我的问题是: 确实有必要为所有选定的列建立索引以便MySQL选择使用索引吗? 如果是这样,在哪里记录(如果有的话)? 如果没有,这里发生了什么?
15 mysql  index  innodb  order-by 


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.