Задайте вопросЗадайте вопрос
 

ОтвеченоA strange problem with 'select' performance

  • 23 апреля 2009 г. 8:13johny quan Медали пользователяМедали пользователяМедали пользователяМедали пользователяМедали пользователя
     
    My statement is as followed:

    I have a table with 2 million records and do a query with the SQL
    "select * from TBL where fld_1=@value"
    (fld_1 is the primary key and defined as char(8)).

    1)when @value is N'10000009', it takes about 0.5 second.
    2)when @value is '10000009',it takes about 0.1 second.
    3)when @value is string which ends with 9 and length is 8 like N'10000019', N'10000129',it takes about 0.5 second.
    4)when @value is sting which ends with 9 and length is lessthan 8,such as N'10000008',it takes about 0.1 second.
    5)when @value is string which does not end with 9, just like N'10000001', N'10000003', N'100015'.
    ,it takes 0.1 second.
    6)when fld_1 is defined as nchar(8) and @value is N'10000009',it takes about 0.1 second.
    7)when all of the indexes(the default primary index also included) are droped,it takes the same time whatever the @value is.

    In my project a complexible SQL is used and the difference described above is expanded about 30 times.

    Does anyone know the special '9'?

Ответы

  • 28 апреля 2009 г. 6:16TiborKMVP, МодераторМедали пользователяМедали пользователяМедали пользователяМедали пользователяМедали пользователя
     Отвечено
    The two are both instant on my server. The first time I execute one fo the queries, it is of course slower since the data isn't in cache, but subsequent are instant (non-measurable). This is confirmed bu SET STATISTICS IO ON, both show 3 logical reads. Both return one row, and both show in execution plan both estimated as well as actual number of rows to be 1.

    But, hang on, Profiler show a marginal difference between the two. The "9" gives me consistently duration of 10-12 microseconds, where the "8" version gives me consistently a duration of 0-1 microseconds. Sometimes, the "9" version show a cpu usage of 15-16. other times it show 0, there the "8" version always show cpu usage of 0. Interesting... I saved the actual execution plan for both to xml file and used WinDiff to compare - identical. All I can say is that it is type related, there is some overhead in the execution engine for the "9" version. My guess is that the contant scan is more costly for the "9" versio because the list of possible values is bigger. Just a guess, though.

    This is an excellent example why we should always match types. If you just make the type for the literal to match the column type, you will not see this problem, as in below:
    select * from T_TEST_9 where ID='10000009'
    select * from T_TEST_9 where ID='10000008' 

    Both above are equally fast, and you will also see a simpler execution plan.
    Tibor Karaszi
    • Помечено в качестве ответаjohny quan 28 апреля 2009 г. 7:14
    •  

Все ответы