使用了错误的SQL索引

时间:2018-09-20 11:43:53

标签: sql sql-server database tsql indexing

我有一张约有1000万行的表,上面有4个索引:

<div id="myModal" class="modal fade" role="dialog" tabindex="-1"
    ng-If="isModalActive">
    <div class="modal-dialog modal-lg">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal"
                    data-target="#myModal" ng-click="closeModal()">&times;</button>
                <h4 class="modal-title"> XML1 & XML2 </h4>
            </div>
            <div class="modal-body" style="text-align: left">

                <div class="panel-group" id="accordion">

                    <div class="panel panel-default">
                        <div class="panel-heading">
                            <h4 class="panel-title" style="text-align: center">
                                <dt>XML1</dt>
                                <a data-toggle="collapse" data-parent="#accordion"
                                    href=#collapse1><span
                                    class='glyphicon glyphicon-chevron-down'></span></a>
                            </h4>
                        </div>
                        <div id="collapse1" class="panel-collapse collapse">
                            <div class="panel-body" style="text-align: left">
                                <button class="button buttonC" ngclipboard
                                    data-clipboard-target="#xmlrequest">Copy to Clipboard</button>

                                <?prettify?>
                                <pre class="prettyprint" id=xmlrequest> {{xmlmess.xml1}}</pre>
                            </div>


                        </div>
                    </div>
                </div>


                <div class="panel panel-default">
                    <div class="panel-heading">
                        <h4 class="panel-title" style="text-align: center">
                            <dt>XML2</dt>
                            <a data-toggle="collapse" data-parent="#accordion"
                                href=#collapse2><span
                                class='glyphicon glyphicon-chevron-down'></span></a>
                        </h4>
                    </div>
                    <div id="collapse2" class="panel-collapse collapse">
                        <div class="panel-body" style="text-align: left">
                            <button class="btn " ngclipboard
                                data-clipboard-target="#xmlresponse" position="fixed">Copy
                                to Clipboard</button>

                            <?prettify?>
                            <pre class="prettyprint" id=xmlresponse> {{xmlmess.xml2}}</pre>
                        </div>
                    </div>
                </div>

            </div>


        </div>
    </div>

</div>

我有以下索引:

  1. DATE:这是归档的CREATEDTS1上的非聚集非唯一索引
  2. PK上的聚集索引,即ORDER_CODE
  3. EMAIL:在EMAIL上

一切正常,但是当我运行一个简单的查询时:

CREATE TABLE ALLTRX2 (
ORDER_CODE nvarchar(20) NOT NULL PRIMARY KEY,
CREATEDTS datetime NULL, 
trx_date nvarchar(11) NULL, 
trx_month nvarchar(8) NULL,
payment_provider nvarchar(255) NULL, 
payment_method nvarchar(100) NULL, 
general_payment_method nvarchar(100) NULL,
amount_initial NUMERIC(30,2) NULL, 
eur_amount NUMERIC(30,2) NULL,
currency nvarchar(20) NULL,
backend_status nvarchar(255) NULL,
general_status nvarchar(50) NULL,
EMAIL nvarchar(255) NULL,
CUSTOMER_ID nvarchar(50) NULL, 
P_UID nvarchar(255) NULL, 
P_NAME nvarchar(255) NULL, 
P_USER nvarchar(255) NULL, 
COUNTRYCODE nvarchar(50) NULL, 
COUNTRY nvarchar(50) NULL,
CUSTOMER_GROUP nvarchar(50) NULL,
DELIVERYADDRESS nvarchar(255) NULL,
BILLINGADDRESS nvarchar(255) NULL, 
CREATEDTS1 DATE NULL )

它执行表扫描而不是索引查找

但是当我这样做

SELECT * FROM ALLTRX2 
WHERE CREATEDTS1>'2018-08-02'

它执行索引搜索。

那对我来说绝对没有意义!

我可以使用WITH(INDEX(date)),但我想以其他方式找到解决方案。

INDEX定义如下:

SELECT * FROM ALLTRX2 
WHERE CREATEDTS1='2018-08-02'

我对数据库管理非常陌生,尽管我经常使用SSMS运行查询,但我并不是索引和数据库维护方面的专家。

任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:0)

您实际上是在寻找日期范围,而不是特定日期。 而且此范围可能不是非常有限的日期范围。

SQL Engine实际上决定扫描日期索引,这还不错。 它通过考虑有关表数据的统计信息来确定此索引选择。

我知道在使用参数集非常不同的情况执行编译的查询(已经确定执行计划的查询)时,会发生此类问题(使用错误的索引选择和性能问题)。

例如,如果您使用一个日期执行存储过程,则它可以选择索引查找,并使用索引查找创建和缓存执行计划。 但是在以后调用具有宽日期范围的存储过程时,索引查找将无法执行查询。

但是您正在运行一个简单的SELECT,不会引起问题。

答案 1 :(得分:0)

我建议您看一下统计信息,因为它们可能很旧,并且SQL Server认为进行扫描比使用索引更为有效。

Error Message

https://docs.microsoft.com/en-us/sql/relational-databases/statistics/statistics?view=sql-server-2017