避免对索引列进行计算

操作系统:Windows 2007

数据库版本:SQL SERVER 2005

发表日期:2014-11-07 16:56:01

今天同事让我看一条SQL,说是在前台查询很快,但是把SQL取出来,在数据库中执行的时候,跑10分钟都不出结果。

看了一下SQL,最后定位到一个视图中的一个子查询上面。该子查询的SQL文本如下:

SELECT  acinv_07.id_item ,
        SUM(acinv_07.dec_endqty) dec_endqty
FROM    acinv_07
WHERE   acinv_07.fiscal_year * 100 + acinv_07.fiscal_period
        = ( SELECT DISTINCT
                   ctlm1101.fiscal_year * 100 + ctlm1101.fiscal_period
                   FROM ctlm1101 WHERE flag_curr = ‘Y‘
                   AND id_oprcode = ‘acinv‘
                   AND acinv_07.id_wh = ctlm1101.id_table)
GROUP BY acinv_07.id_item

在acinv_07表上的列fiscal_year和列fiscal_period是有索引的。但是,如果对索引列进行运算,就会导致原本可以走索引的走不了索引。于是,动手改写成如下SQL:

SELECT    id_item ,
                    SUM(dec_qty) dec_qty
          FROM      dpurreq_03
          GROUP BY  id_item
        ) a ,
        ( SELECT    a.id_item ,
                    SUM(a.dec_endqty) dec_endqty
          FROM      acinv_07 a ,
                    ( SELECT DISTINCT
                                ctlm1101.fiscal_year ,
                                ctlm1101.fiscal_period ,
                                id_table
                      FROM      ctlm1101
                      WHERE     flag_curr = ‘Y‘
                                AND id_oprcode = ‘acinv‘
                    ) b
          WHERE     a.fiscal_year = b.fiscal_year
                    AND a.fiscal_period = b.fiscal_period
                    AND a.id_wh = b.id_table
          GROUP BY  a.id_item

再执行,4s钟左右就可以跑出结果了。

对于开发来说,纯粹是为了实现把结果数据展示出来,而不会过多考虑SQL的性能问题。

总结

写SQL时,不到万不得已,不要对索引列进行计算。

时间: 2024-11-05 12:24:16

避免对索引列进行计算的相关文章

SQL Server-聚焦计算列或计算列持久化查询性能(二十二)

前言 上一节我们详细讲解了计算列以及计算列持久化的问题,本节我们依然如前面讲解来看看二者查询性能问题,简短的内容,深入的理解,Always to review the basics. 持久化计算列比非持久化计算列性能要好 我们开始创建两个一样的表并都插入100条数据来进行比较,对于计算列我们重新进行创建计算列和非计算列持久化. CREATE TABLE [dbo].[ComputeColumnCompare] (ID INT, FirstName VARCHAR(100), LastName C

SQL Server 执行计划利用统计信息对数据行的预估原理二(为什么复合索引列顺序会影响到执行计划对数据行的预估)

本文出处:http://www.cnblogs.com/wy123/p/6008477.html 关于统计信息对数据行数做预估,之前写过对非相关列(单独或者单独的索引列)进行预估时候的算法,参考这里. 今天来写一下统计信息对于复合索引在预估时候的计算方法和潜在问题. 本文原形来自于是个实际业务问题,某SQL在利用一个符合索引做查询的时候,发现始终会出现预估误差较大的情况, 而改变复合索引的列顺序,这个预估行数的误差会发生变化, 也就是说,Create  index idx_index1 ON T

检查外键列是否是索引列的两个语句

本文摘自<oracle 索引技术> 第37页和第38页 检查外键列是否是索引列的语句之一: select distinct a.owner  owner, a.constraint_name cons_name, a.table_name tab_name, b.column_name  cons_column, nvl(c.column_name,'***Check index***') ind_column from dba_constraints a,      dba_cons_col

SQL Server创建复合索引时,复合索引列顺序对查询的性能影响

说说复合索引 写索引的博客太多了,一直不想动手写,有一下两个原因:一是觉得有炒剩饭的嫌疑,有兄弟曾说:索引吗,只要在查询条件上建索引就行了,真的可以这么暴力吗?二来觉得,索引是个非常大的话题,很难概括出所有的情况,你不整出点新意来,倒是有抄袭照搬的嫌疑 既然写了,就写一点稍微不一样的东西出来,好了,废话打住,开搞 /* 20160814备注:今天发现一个类似的文章:http://www.cnblogs.com/fly_zj/archive/2012/08/11/2633629.html : 可以

【转】Oracle索引列NULL值引发执行计划该表的测试示例

有时开发进行表结构设计,对表字段是否为空过于随意,出现诸如id1=id2,如果允许字段为空,因为Oracle中空值并不等于空值,有可能得到意料之外的结果.除此之外,最关键的是,NULL会影响oracle的执行计划. 以下为NULL影响执行计划的测试示例. /*1.构建test表,其中create table方式建立的test表结构object_id非空*,走索引/ SELECT Count(*) FROM all_objects WHERE object_id IS NOT NULL; --41

非索引列上的统计 &lt;第二篇&gt;

非索引列上的统计 有时候,可能在连接或过滤条件中的列上没有索引.即使对这种非索引列,如果查询优化器知道这些列的数据分布(统计),它也很可能做出最佳的选择. 除了索引上的统计,SQL Server可以在没有索引的列上建立统计.即使不是索引列,当你开启了SQL Server自动创建统计功能,SQL Server就自动在执行WHERE.JOIN等查询列上创建统计.数据分布的信息或者特定值出现在非索引列上的可能性,都能够帮助查询优化器确定最优的处理策略.即使查询优化器不能真正使用索引来定位这些列,这也仍

索引列上的统计 &lt;第一篇&gt;

一.索引在查询优化中的角色 SQL Server的查询优化器是基于开销的优化器.它通过确认选择性.数据的唯一性以及过滤数据(通过WHERE或JOIN子句)所使用的列来决定最佳的数据访问机制.统计与索引一同存在,但是它们也作为断言的一部分存在于没有索引的列上. 作为谓词引用的列中数据分布的最新信息帮助优化器确定所使用的查询策略.在SQL Server中,这个信息以统计的形式维护,这对于基于开销的优化器创建一个有效的查询执行计划是很重要的.通过统计,优化器能做出返回结果集或中间结果集所花费时间的精确

关于数据库表中的索引及索引列的CRUD

-- 查询一个数据库表中的索引及索引列use [RuPengWangDB]GOSELECT  indexname = a.name , tablename = c. name , indexcolumns = d .name , a .indidFROM    sysindexes a JOIN sysindexkeys b ON a .id = b .id  AND a .indid = b.indid        JOIN sysobjects c ON b .id = c .id    

关于复合索引中的2个索引列谁在前谁在后的进一步讨论--实践篇

关于复合索引中的2个索引列谁在前谁在后的进一步讨论--实践篇: 上一次在长老的QQ群里边说了这么一个例子: create table test_pk( id varchar2(10), create_dt date); alter table test_pk modify (id varchar2 (30 )); insert into test_pk select object_id, sysdate from dba_objects; commit 需要执行的查询是: select * fr