具有动态谓词的表的最佳索引

2024-03-01

我想优化SQL Server中下表的查询速度

CREATE TABLE [dbo].[PriceNodeLookupIndex]
(
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [PriceNodeId] [int] NOT NULL,
    [ItemId] [int] NOT NULL,
    [OptionValueId1] [int] NULL,
    [OptionValueId2] [int] NULL,
    [OptionValueId3] [int] NULL,
    [OptionValueId4] [int] NULL,
    [OptionValueId5] [int] NULL,
    [OptionValueId6] [int] NULL,
    [OptionValueId7] [int] NULL,
    [OptionValueId8] [int] NULL,
    [OptionValueId9] [int] NULL,
    [OptionValueId10] [int] NULL,
    [OptionValueId11] [int] NULL,
    [OptionValueId12] [int] NULL,
    [OptionValueId14] [int] NULL,
    [OptionValueId15] [int] NULL,
    [OptionValueId13] [int] NULL,
    [OptionValueId16] [int] NULL,
    [OptionValueId17] [int] NULL,
    [OptionValueId18] [int] NULL,
    [OptionValueId19] [int] NULL,
    [OptionValueId20] [int] NULL,

    CONSTRAINT [PK_PriceNodeLookupIndex] 
        PRIMARY KEY NONCLUSTERED 
)

针对该表运行的查询如下所示:

SELECT PriceNodeId 
FROM PriceNodeLookupIndex 
WHERE ItemId = 2345
  AND OptionValueId5 = 63423
  AND OptionValueId11 = 97543
  AND OptionValueId13 = 39452

但是,那OptionValueId谓词列表是动态生成的,因此它可以是以下任意组合OptionValueId列。

因此下一个查询可能是

SELECT PriceNodeId 
FROM PriceNodeLookupIndex     
WHERE ItemId = 2345
  AND OptionValueId7 = 45340
  AND OptionValueId14 = 5693

查询中只会使用任何列之一。

目前的指数是

  • 非聚集索引Id
  • 聚集索引PriceNodeId

and:

CREATE NONCLUSTERED INDEX [PriceNodeLookupIndex_All] 
ON [dbo].[PriceNodeLookupIndex] ([ItemId] ASC)
INCLUDE ([OptionValueId1], [OptionValueId2], [OptionValueId3],
         [OptionValueId4], [OptionValueId5], [OptionValueId6],
         [OptionValueId7], [OptionValueId8], [OptionValueId9],
         [OptionValueId10], [OptionValueId11], [OptionValueId12],
         [OptionValueId13], [OptionValueId14], [OptionValueId15],
         [OptionValueId16], [OptionValueId17], [OptionValueId18],
         [OptionValueId19], [OptionValueId20])

当我运行执行计划时,它使用大索引,但也建议目标索引,该索引仅适用于确切的组合OptionValueId列(对我来说没用)。

整个应用程序的性能由这些查询的速度决定。

有没有人对我如何提高这些查询的速度有任何建议,或者这是否已经达到最好的程度?


因为您违反了数据库建模的第一范式(通过不正当的手段 - apocope),所以您无法优化此类查询。

First您应该通过将此伪数组 (OptionValueId1 ... OptionValueId20) 外部化到如下表中来重新规范化您的模型:

CREATE TABLE dbo.PriceNodeLookupIndex_values
(   Id int        NOT NULL REFERENCES dbo.PriceNodeLookupIndex ON DELETE CASCADE,
    Position      INT NOT NULL,
    OptionValue   INT NOT NULL,
    CONSTRAINT    PK_PriceNodeLookupIndex_values PRIMARY KEY(Id, Position));
CREATE INDEX X ON dbo.PriceNodeLookupIndex_values (OptionValue);

Second,删除原始表中的所有 OptionValueId1 ... OptionValueId20 。

Third使用数据透视运算符创建一个视图来模拟异常表。例如,您应该为此视图指定名称“dbo.PriceNodeLookupIndex2”。

Last,测试为 dbo.PriceNodeLookupIndex2 重写的查询的速度。

每当你不尊重数据建模概念(如正常形式)的精神时,性能都会很丑陋......

如果您希望用户可以插入或更新视图,请编写两个 INSTEAD OF 触发器来无缝地完成这项工作。

特别是在你的原始表中,许多列将具有 NULL 值(实际上是一个标记),几乎有 4 个字节没有值......结果将是一个肥胖的表,其中有很多空的东西,这也会降低性能。

顺便问一下,为什么 PriceNodeLookupIndex 使用非聚集主键?你喜欢搬起石头砸自己的脚吗?

我不推荐的另一种方法是为原始表使用聚集列存储索引......

作为 SQL 命令的补充(但用法语......稍后将用英语):模型化:viol de la première forme normale par « apocope » http://mssqlserver.fr/modelisation-viol-de-la-premiere-forme-normale-par-apocope/

为了好玩,该视图与原始表完全相同:

CREATE VIEW dbo.V_PriceNodeLookupIndex
AS
SELECT Id, PriceNodeId, ItemId, 
       [1] AS OptionValueId1,
       [2] AS OptionValueId2,
       [3] AS OptionValueId3,
       [4] AS OptionValueId4,
       [5] AS OptionValueId5,
       [6] AS OptionValueId6,
       [7] AS OptionValueId7,
       [8] AS OptionValueId8,
       [9] AS OptionValueId9,
       [10] AS OptionValueId10,
       [11] AS OptionValueId11,
       [12] AS OptionValueId12,
       [13] AS OptionValueId13,
       [14] AS OptionValueId14,
       [15] AS OptionValueId15,
       [16] AS OptionValueId16,
       [17] AS OptionValueId17,
       [18] AS OptionValueId18,
       [19] AS OptionValueId19,
       [20] AS OptionValueId20
FROM   (SELECT PN.Id, PN.PriceNodeId, PN.ItemId, V.Position, V.OptionValue
        FROM   questions_76231541.PriceNodeLookupIndex AS PN
               LEFT OUTER JOIN questions_76231541.PriceNodeLookupIndex_values AS V
                  ON PN.Id = V.Id) AS SRC
PIVOT  (MAX(OptionValue)
        FOR Position IN ( [1],  [2],  [3],  [4],  [5],  [6],  [7],  [8],  [9], [10], 
                         [11], [12], [13], [14], [15], [16], [17], [18], [19], [20])
       ) AS PV;
GO
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

具有动态谓词的表的最佳索引 的相关文章

  • 如何使用 Windows 身份验证指定 Windows 用户从 ASP 连接到 MS SQL Server 数据库

    我已经尝试了一个多月的时间来将这里的 ASP 脚本连接到 SQL Server 数据库 但每次我使用这个连接字符串时 Data Source dbServer01 Initial Catalog POS123 Integrated Secu
  • SQL Join 列上类似于另一列[重复]

    这个问题在这里已经有答案了 可能的重复 mysql连接查询使用like https stackoverflow com questions 1930809 mysql join query using like 我想要进行连接 其中一列包含
  • 检查两个“select”是否相等

    有没有办法检查两个 非平凡的 选择是否等效 最初我希望两个选择之间有形式上的等价 但是答案在证明 sql 查询等价性 https stackoverflow com questions 56895 proving sql query equ
  • 如何将 数组传递给存储过程

    我有一个清单索赔数据在 C 中 它有三个项目 日期 类型和描述 其中可以有多行 如下所示 索赔数据 Date Type Description 01 02 2012 Medical Its a medical 05 02 2013 Thef
  • JDBC插入实数数组

    我试图将一个真实的数组插入到 postgresql 数组中 该表的定义是 String sqlTable CREATE TABLE IF NOT EXISTS ccmBlock sampleId INTEGER block REAL 插入内
  • 数据库字段中的逗号分隔值

    我有一个产品表 该表中的每一行对应一个产品 并由唯一的 ID 标识 现在 每个产品都可以有多个与该产品关联的 代码 例如 Id Code 0001 IN ON ME OH 0002 ON VI AC ZO 0003 QA PS OO ME
  • H2 用户定义的聚合函数 ListAgg 不能在第一个参数上使用 DISTINCT 或 TRIM()

    所以我有一个 DB2 生产数据库 我需要在其中使用可用的函数 ListAgg 我希望使用 H2 的单元测试能够正确测试此功能 不幸的是H2不直接支持ListAgg 但是 我可以创建一个用户定义的聚合函数 import java sql Co
  • 如何在MYSQL中将整个字符串小写并保持第一个大写[重复]

    这个问题在这里已经有答案了 我的表栏目 我预期的输出会在列中发生变化 Smith Allen Doyle Dennis Baker Waker 这是我尝试过的 但不起作用 UPDATE TABLE employee SET last nam
  • SQL Server 连接其他表中不存在的位置

    Service Asset AssetService Id Name Id Name AssetId ServiceId
  • 提高第一个查询的性能

    如果执行以下数据库 postgres 查询 则第二次调用要快得多 我猜第一个查询很慢 因为操作系统 linux 需要从磁盘获取数据 第二个查询受益于文件系统级别和 postgres 中的缓存 有没有一种方法可以优化数据库以快速获得结果fir
  • 如何从 SQL Server 2008 查询结果中删除“NULL”

    我有一个包含 59 列和超过 17K 行的表 很多行都有NULL在某些列中 我想删除NULL以便查询返回空白 而不是NULL 我可以运行一些更新功能来替换所有NULL with 使用 SQL Server 2008R2 Management
  • 是否有适用于 SQL Server Express 的 SQL Server Profiler? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 是否有适用于 SQL Server Express 的 SQL Server Profiler 也许是开源的 或者也许只是一个可以帮助我查
  • MYSQL从每个类别中随机选择一条记录

    我有一个数据库Items表看起来像这样 id name category int 有几十万条记录 每个item可以是 7 种不同的之一categories 对应于categories table id category 我想要一个从每个类别
  • 我不断收到错误“关系 [TABLE] 不存在”

    我一直在尝试查询数据库中的两个表 在服务器资源管理器中 我可以看到两个表 甚至可以看到其中的列 我们将它们称为 Schema table1 和 Schema table2 其中 Schema 的第一个字母大写 我尝试运行以下查询 selec
  • 如何使用 SQL Server 2008 将行复制到同一个表中

    A 到目前为止我的方式 sqlCommand CommandText INSERT Table1 column1 column2 column3 SELECT column1 column2 column3 FROM Table1 WHER
  • 同时从2个表中删除?

    我正在使用 asp net 和 sql 服务器 我有 2 个表 类别和产品 在产品表中 我的categoryId 为FK 我想要做的是 当我从类别表中删除类别时 我希望该类别中的所有产品都将在产品表中删除 如何才能做到这一点 我更喜欢使用存
  • 快速将列的副本添加到 MySQL 表

    我需要一种快速的方法来复制表中的 DATETIME 列并为其指定一个新名称 我的表中有一个名为 myDate 的列 名为 myResults 我需要一个查询来在名为 newDate 的表中创建一个新列 该列的数据与 myDate 列完全相同
  • SQL Server 数据库架构版本控制和更新

    对于我的应用程序 我必须支持更新方案 并且数据库可能会受到影响 我希望能够从旧版本更新到最新版本 而无需安装中间版本 例如 假设我有版本 A 最旧的版本 B 中间版本 和 C 新版本 我希望能够将版本 A 直接更新到版本 C 对于应用程序文
  • 通知设置的数据库设计

    用户可以打开或关闭 他的通知设置 帐户 用于通知 例如 更改帐户资料信息 收到新消息等 通知可以通过电子邮件或手机 推送或短信 发送 用户可以只有 1 封电子邮件和多个手机设备 有什么方法可以改进以下数据库设计或者您会采取不同的方式吗 让我
  • 从 Sharepoint 到 SQL Server 的实时同步

    我见过许多将 SQL Server 数据同步到 SharePoint 的解决方案 但没有见过将 SharePoint 列表同步到 SQL Server 的解决方案 有谁知道解决方案吗 商业化就好了 或者 我需要编写一个 Web 部件来创建多

随机推荐

  • 在 PHP 闭包中注入代码

    我有一个已经定义的闭包 我想在执行它时在其中注入代码 这是一个例子 predefined print my predefined injected code br closure function print hello br call u
  • 有效证书上的 axios 证书已过期[关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 编辑 这是由于https letsencrypt org docs dst root ca x3 expiration septe
  • 流星从复选框 switchChange 中检索 true/false 值

    我有一个附加到复选框的事件处理程序 我正在使用引导开关http www bootstrap switch org http www bootstrap switch org 我试图将 true 或 false 的状态值获取到变量中 以便我可
  • Windows 或 ASP.NET 服务中的 System.Drawing

    根据MSDN http msdn microsoft com en us library system drawing aspx 在 中使用类并不是一个特别好的主意系统图Windows 服务或 ASP NET 服务中的命名空间 现在我正在开
  • 将证书从智能卡复制到计算机

    是否可以将证书从智能卡复制到计算机并 用它来登录某个站点 在 Mac 上 这些证书出现在钥匙串中 并且可以保存到磁盘 但我不确定如何强制站点提示对话框屏幕以选择证书 连接智能卡后 会出现提示并要求选择证书 智能卡包含由封装在 X509 证书
  • 隐藏重复行 SSRS 2008 R2

    我的报告中出现重复的数据 因为源表有重复的数据 在不创建组的情况下 我想隐藏重复的数据写入表达式 所以我做了什么 我选择表行并为表行的隐藏属性添加一个表达式 表情就像是 上一个 字段 ID 值 字段 ID 值 但它不起作用 仍然显示重复的数
  • 选择组中第 i 个 jQuery 对象比 $($(".someclass")[i])) 更简单的方法?

    所以我试图循环遍历 someclass 的成员 不是 DOM 元素 而是它们的 jQuery 对应元素 我一直在使用 someclass i 但这非常丑陋 有更自然的方法来做到这一点吗 你可以使用eq http api jquery com
  • 动态控件组和复选框无样式

    所以我尝试将动态内容直接加载到我的复选框容器 group checkboxes 中 div div 这是我正在运行的用于填充容器的语句 group checkboxes append fieldset fieldset
  • 使重叠内容的容器适合最大孩子的高度

    我正在构建一个在 3 个引号之间旋转的轮播 幻灯片类型小部件 假设标记如下所示 div class carousel blockquote blockquote blockquote blockquote blockquote blockq
  • Laravel 中的“请提供有效的缓存路径”错误

    我复制了一个正在运行的 Laravel 应用程序并将其重命名以用于另一个应用程序 我删除了供应商文件夹并再次运行以下命令 composer self update composer update npm install bower inst
  • 表格页脚自动跨过表格宽度

    我有一张桌子 里面有动态列数取决于我收到的数据 我有一个标签需要分布在所有列上 与表中的列数无关 table thead tr th span ColA span th th span ColB span th th span Col br
  • 为什么gcc中malloc将值初始化为0?

    可能各个平台的情况不一样 但是 当我使用 gcc 编译并运行下面的代码时 我在 ubuntu 11 10 中每次都得到 0 include
  • Microsoft.FSharp.Math.Matrix 发生了什么?

    有点奇怪 这个类类型如何从 VS2010 发布的 F 中删除 有谁知道它去哪儿了 或者现在在哪里 它位于 F powerpack 中 F 团队将其用于 不稳定 代码 这些代码的发布和更新频率将高于 F 和库的主要版本 请注意 该代码仍然是高
  • 与scala反射库不一致

    我无法理解为什么在 2 11 1 中使用 scala 的运行时反射会给出看似不一致的结果 我正在尝试检查 java 对象中包含的字段的类型 如下所示 import java util List import java util ArrayL
  • 如何在jquery中缓慢改变背景属性?

    我想要为背景设置动画 但它不会随 animate 改变 document ready function menu hover function this stop animate background moz radial gradient
  • 如何防止在 Cloudflare 上暴露源 IP 地址?

    在 Cloudflare DNS 设置页面上 它指出An A AAAA CNAME or MX record is pointed to your origin server exposing your origin IP address
  • 列表框数据模板 - 只能通过单击子元素来选择项目,而不仅仅是项目上的任何位置

    我有一个带有项目数据模板的列表框 问题在于 仅通过单击项目上的任意位置无法选择项目 必须选择项目 我必须单击特定的子元素才能使其实际工作 我的项目有一个图像和一个文本块 如果我将鼠标悬停在图像或文本块上 我实际上会看到悬停效果 如果我将鼠标
  • Spring-boot Resttemplate response.body 为 null 而拦截器清楚地显示 body

    使用 Spring boot 1 5 10 RELEASE 我得到的 response body 为 null 这是我使用 RestTemplate 的方式 RestTemplate restTemplate new RestTemplat
  • Maven javadoc + 自定义 doclet

    从命令行调用 mvn 时如何指定 dolect 工件 mvn clean install javadoc javadoc Ddoclet my Doclet DdocletArtifact 你应该添加这样的东西到你的pom xml
  • 具有动态谓词的表的最佳索引

    我想优化SQL Server中下表的查询速度 CREATE TABLE dbo PriceNodeLookupIndex Id int IDENTITY 1 1 NOT NULL PriceNodeId int NOT NULL ItemI