Categories
сметачи

mysql & unix_timestamp re-evaluation

Струва ми се, че mysql вика отново и отново при всеки where фукнцията unix_timestamp, дори когато тя е с аргумент – константа.

Нека имаме следната таблица:
CREATE TABLE `baba` (
`n` int(11) default NULL,
`d` datetime default NULL
) TYPE=MyISAM

и освен това един около милион записа, за които в d има произволна дата, а в n се намира unix timestamp-а на тази дата.

И сега направим няколко заявки:

  1. mysql> select count(*) from baba where n < = 315871200;
    +----------+
    | count(*) |
    +----------+
    |   345610 |
    +----------+
    1 row in set (0.21 sec)
    
  2. mysql>select count(*) from baba where d < = from_unixtime(315871200);
    +----------+
    | count(*) |
    +----------+
    |   345610 |
    +----------+
    1 row in set (0.25 sec)
    
  3. mysql> select from_unixtime(315871200);
    +--------------------------+
    | from_unixtime(315871200) |
    +--------------------------+
    | 1980-01-05 00:00:00      |
    +--------------------------+
    1 row in set (0.00 sec)
    
  4. mysql> select count(*) from baba where d <= '1980-01-05 00:00:00';
    +----------+
    | count(*) |
    +----------+
    |   345610 |
    +----------+
    1 row in set (0.25 sec)
    
  5. mysql> select count(*) from baba where n < = unix_timestamp('1980-01-05 00:00:00');
    +----------+
    | count(*) |
    +----------+
    |   345610 |
    +----------+
    1 row in set (3.92 sec)
    
  6. mysql> select count(*) from baba;
    +----------+
    | count(*) |
    +----------+
    |  1000010 |
    +----------+
    1 row in set (0.00 sec)
    
  7. mysql> select benchmark(1000010, unix_timestamp('1980-01-05 00:00:00'));
    +-----------------------------------------------------------+
    | benchmark(1000010, unix_timestamp('1980-01-05 00:00:00')) |
    +-----------------------------------------------------------+
    |                                                         0 |
    +-----------------------------------------------------------+
    1 row in set (3.70 sec)
    
  8. mysql> select benchmark(1000010, from_unixtime(315871200));
    +----------------------------------------------+
    | benchmark(1000010, from_unixtime(315871200)) |
    +----------------------------------------------+
    |                                            0 |
    +----------------------------------------------+
    1 row in set (3.70 sec)
    

Сега след дългите и скучни заявки малка интерпретация от моя страна.
Заявки 1,2 и 4 минават за горе-долу едно и също време, следователно в заявка 2 функцията from_unixtime се вика само веднъж, което е адски логично – аргументът, който и е подаден е константа и няма смисъл при всеки обработен ред да се вика функцията отново и отново.

Сякаш, обаче заявка 5 никак не се подчинаява не следната логика. Изглежда, че сумата на времената за изпълнение на заявки 8 и 1 е близо до времето за изпълнение на заявка 5. Дали unix_timestamp все пак не се вика за всеки разгледан ред от таблицата (в нашия случай се прави full table scan), въпреки че има за аргумент константа?

Последвалите разследвания… в следващата серия.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.