Оптимизировать запрос на подсчет MySQL, полная информация предоставлена

У меня есть этот запрос, который длится более 3 минут. Я ищу оптимизацию для запуска через несколько секунд:

SELECT Count(DISTINCT l.licitatii_id) c 
FROM   licitatii_ue l 
       INNER JOIN domenii_licitatii dl 
               ON l.licitatii_id = dl.licitatii_id 
                  AND dl.tip_licitatie = '2' 
       INNER JOIN domenii d 
               ON dl.domenii_id = d.domenii_id 
                  AND d.tip_domeniu = '1' 
                  AND d.status = 1 
WHERE  l.status = 1 
       AND l.data_limita >= '1357768800' 

объяснение показывает:

*** row 1 ***
          table:  d
           type:  ref
  possible_keys:  PRIMARY,key_status_tip_domeniu,ind_v1
            key:  key_status_tip_domeniu
        key_len:  9
            ref:  const,const
           rows:  39
          Extra:  Using where; Using index
*** row 2 ***
          table:  dl
           type:  ref
  possible_keys:  PRIMARY,licitatii_id,licitatii_id_2
            key:  PRIMARY
        key_len:  5
            ref:  web1db1.d.domenii_id,const
           rows:  1882
          Extra:  Using index
*** row 3 ***
          table:  l
           type:  eq_ref
  possible_keys:  PRIMARY,data_limita
            key:  PRIMARY
        key_len:  4
            ref:  web1db1.dl.licitatii_id
           rows:  1
          Extra:  Using where

Схема:

<Сильный> licitatii_ue

  PRIMARY KEY (`licitatii_id`),
  UNIQUE KEY `nr_ue` (`nr_ue`),
  KEY `nume` (`nume`),
  KEY `tip_licitatie` (`tip_licitatie`),
  KEY `surse_ue_id` (`surse_ue_id`),
  KEY `data_publicarii` (`data_publicarii`),
  KEY `tara_id` (`tara_id`),
  KEY `creat` (`creat`),
  KEY `data_limita` (`data_limita`),
  FULLTEXT KEY `nume_fulltext` (`nume`,`descriere`)
) ENGINE=MyISAM

/*Index Information*/
---------------------

Table         Non_unique  Key_name         Seq_in_index  Column_name      Collation  Cardinality  Sub_part  Packed  Null    Index_type  Comment  
------------  ----------  ---------------  ------------  ---------------  ---------  -----------  --------  ------  ------  ----------  ---------
licitatii_ue           0  PRIMARY                     1  licitatii_id     A               136456    (NULL)  (NULL)          BTREE                
licitatii_ue           0  nr_ue                       1  nr_ue            A               (NULL)    (NULL)  (NULL)  YES     BTREE                
licitatii_ue           1  nume                        1  nume             A                68228    (NULL)  (NULL)          BTREE                
licitatii_ue           1  tip_licitatie               1  tip_licitatie    A                   13    (NULL)  (NULL)  YES     BTREE                
licitatii_ue           1  surse_ue_id                 1  surse_ue_id      A                    1    (NULL)  (NULL)          BTREE                
licitatii_ue           1  data_publicarii             1  data_publicarii  A               136456    (NULL)  (NULL)  YES     BTREE                
licitatii_ue           1  tara_id                     1  tara_id          A                   41    (NULL)  (NULL)  YES     BTREE                
licitatii_ue           1  creat                       1  creat            A               136456    (NULL)  (NULL)  YES     BTREE                
licitatii_ue           1  data_limita                 1  data_limita      A                  770    (NULL)  (NULL)  YES     BTREE                
licitatii_ue           1  nume_fulltext               1  nume             (NULL)               1    (NULL)  (NULL)          FULLTEXT             
licitatii_ue           1  nume_fulltext               2  descriere        (NULL)               1    (NULL)  (NULL)  YES     FULLTEXT   

<Сильный> domenii_licitatii

  PRIMARY KEY (`domenii_id`,`tip_licitatie`,`licitatii_id`),
  KEY `licitatii_id` (`licitatii_id`,`tip_licitatie`),
  KEY `licitatii_id_2` (`licitatii_id`)
) ENGINE=InnoDB 

/*Index Information*/
---------------------

Table              Non_unique  Key_name        Seq_in_index  Column_name    Collation  Cardinality  Sub_part  Packed  Null    Index_type  Comment  
-----------------  ----------  --------------  ------------  -------------  ---------  -----------  --------  ------  ------  ----------  ---------
domenii_licitatii           0  PRIMARY                    1  domenii_id     A                   20    (NULL)  (NULL)          BTREE                
domenii_licitatii           0  PRIMARY                    2  tip_licitatie  A                  228    (NULL)  (NULL)          BTREE                
domenii_licitatii           0  PRIMARY                    3  licitatii_id   A               430634    (NULL)  (NULL)          BTREE                
domenii_licitatii           1  licitatii_id               1  licitatii_id   A               430634    (NULL)  (NULL)          BTREE                
domenii_licitatii           1  licitatii_id               2  tip_licitatie  A               430634    (NULL)  (NULL)          BTREE                
domenii_licitatii           1  licitatii_id_2             1  licitatii_id   A               430634    (NULL)  (NULL)          BTREE                

<Сильный> Domenii

  PRIMARY KEY (`domenii_id`),
  KEY `key_status_tip_domeniu` (`status`,`tip_domeniu`),
  KEY `ind_v1` (`domenii_id`,`tip_domeniu`,`status`),
  KEY `parent_id` (`parent_id`)
) ENGINE=InnoDB 

/*Index Information*/
---------------------

Table    Non_unique  Key_name                Seq_in_index  Column_name  Collation  Cardinality  Sub_part  Packed  Null    Index_type  Comment  
-------  ----------  ----------------------  ------------  -----------  ---------  -----------  --------  ------  ------  ----------  ---------
domenii           0  PRIMARY                            1  domenii_id   A                   79    (NULL)  (NULL)          BTREE                
domenii           1  key_status_tip_domeniu             1  status       A                    4    (NULL)  (NULL)  YES     BTREE                
domenii           1  key_status_tip_domeniu             2  tip_domeniu  A                   11    (NULL)  (NULL)          BTREE                
domenii           1  ind_v1                             1  domenii_id   A                   79    (NULL)  (NULL)          BTREE                
domenii           1  ind_v1                             2  tip_domeniu  A                   79    (NULL)  (NULL)          BTREE                
domenii           1  ind_v1                             3  status       A                   79    (NULL)  (NULL)  YES     BTREE                
domenii           1  parent_id                          1  parent_id    A                   79    (NULL)  (NULL)          BTREE  
2
nl ja de

2 ответы

Вам действительно нужны сложные индексы на ваших таблицах.

table             index
licitatii         ( status, data_limita, licitatii_id )
domenii_licitatii ( licitatii_id, tip_licitatie )
domenii           ( domenii_id, tip_domeniu, status )

У вас должны быть составные ключи, которые помогут оптимизировать ваши соединения и где критерии. Кроме того, поскольку я включил их, механизм запроса может находить значения для соединений непосредственно из индексов вместо того, чтобы возвращаться к страницам фактических данных. Если в индексе есть только один столбец, запрос затем перейдет к исходным данным для соединения. Посмотрите, что он делает для вас.

Хорошо, да, два других индекса, и вы добавили третий - не помогли. Затем я попытался бы обратить вспять запрос ... Не точно зная данные, но похоже, что они представляют собой некоторые элементы категорий поиска. Пытаться

select STRAIGHT_JOIN
      Count(DISTINCT dl.licitatii_id) c
   from
      domenii d
         join domenii_licitatii dl
            on d.domenii_id = dl.domenii_id
           AND dl.tip_licitatie = '2'
            JOIN licitatii_ue L
               on dl.licitatii_id = L.licitatii_id
              AND L.status = 1
              AND L.Data_Limita >= '1357768800'
   where
          d.tip_domeniu = '1'
      and d.status = 1

добавлен Pentium10

Объясните следующее:

+---+--------+----+--------+---------------------------------------+------------------------+---+----------------------------+------+--------------------------+
| 1 | SIMPLE | d  | ref    | PRIMARY,key_status_tip_domeniu,ind_v1 | key_status_tip_domeniu | 9 | const,const                |   39 | Using where; Using index |
| 1 | SIMPLE | dl | ref    | PRIMARY,licitatii_id,licitatii_id_2   | PRIMARY                | 5 | web1db1.d.domenii_id,const | 1882 | Using index              |
| 1 | SIMPLE | L  | eq_ref | PRIMARY,data_limita,i1                | PRIMARY                | 4 | web1db1.dl.licitatii_id    |    1 | Using where              |
+---+--------+----+--------+---------------------------------------+------------------------+---+----------------------------+------+--------------------------+
1
добавлено
@ Pentium10, см. Пересмотренный вариант
добавлено автор DRapp, источник
@ Pentium10, не зная данных о том, сколько записей на каком уровне/состоянии я пытался заставить альтернативный подход, который, возможно, имел меньшую запись, установленную в первой позиции таблицы. Это и использование STRAIGHT_JOIN помогло во многих запросах в прошлом переопределить то, что хочет сделать оптимизатор. Иногда это работает, иногда нет, а просто другой подход к данным.
добавлено автор DRapp, источник
Я добавил первый индекс, другой тоже уже был там. Это не помогает. Его вообще нет.
добавлено автор Pentium10, источник
Я добавил объяснение к вашему ответу. Сохраняется только первичный индекс. Какова была логика переписывания запроса?
добавлено автор Pentium10, источник

Здесь я переместил предложение WHERE в конец в подзапрос в начале, поэтому ему не нужно фильтровать больше строк, созданных в конце INNER JOIN s в конце , он уже правильно фильтруется во время первого INNER JOIN . Это выполняется 2 запроса, но это должно быть быстрее.

SELECT Count(DISTINCT l.licitatii_id) c 
FROM   (SELECT DISTINCT licitatii_id 
        FROM   licitatii_ue l 
        WHERE  l.status = 1 
        AND    l.data_limita >= '1357768800' 
        ) l 
       INNER JOIN domenii_licitatii dl 
               ON l.licitatii_id = dl.licitatii_id 
                  AND dl.tip_licitatie = '2' 
       INNER JOIN domenii d 
               ON dl.domenii_id = d.domenii_id 
                  AND d.tip_domeniu = '1' 
                  AND d.status = 1 
0
добавлено
это не помогает, он работает в течение 4 мин 56 сек.
добавлено автор Pentium10, источник
Был ли объединенный индекс в исходном предложении WHERE ? Похоже, что они есть для других столбцов в INNER JOIN s. Попробуйте создать объединенный индекс в l.status и l.data_limita в таблице licitatii_ue и повторите описанное выше.
добавлено автор Paul Stanley, источник
phpGeeks
phpGeeks
3 620 участник(ов)

Best PHP chat Еще: @dbGeeks - базы данных @phpGeeksJunior - новичкам @moscowProgers - IT Москва @ebanoePhp - весёлый канал о PHP @laravel_pro - Laravel @jobGeeks - вакансии @jsChat - JS Правила: https://t.me/phpGeeks/764859 ДР - 28.03.2016

DBA - русскоговорящее сообщество
DBA - русскоговорящее сообщество
1 345 участник(ов)

Общаемся и обсуждаем темы, посвященные DBA, PostgreSQL, Redis, MongoDB, MySQL, neo4j, riak и т.д. См. также: @devops_ru, @kubernetes_ru, @docker_ru, @nodejs_ru Рекомендуем сразу отключить уведомления, чтобы пребывание здесь было полезным и комфортным.

PHP
PHP
1 309 участник(ов)

Группа про современный PHP. Обсуждаем ООП, TDD, BDD, DDD, SOLID, GRASP и прочие крутые базворды Для ознакомления: https://gist.github.com/mkusher/711bd46f0b62fbae851182e6fb3b1839 Группа PHP для новичков @phpGeeksJunior Вакансии: https://t.me/fordev

PHP — вакансии, поиск работы и аналитика
PHP — вакансии, поиск работы и аналитика
1 251 участник(ов)

Публикуем вакансии и запросы на поиск работы по направлению PHP, Laravel, Symfony, Yii и т.д. Здесь всё: full-time, part-time, remote и разовые подработки. См. также: @qa_jobs, @devops_jobs, @javascript_jobs, @nodejs_jobs, @uiux_jobs, @products_jobs

MySQL
MySQL
995 участник(ов)

The group is about MySQL. For code use hastebin.com. Admin: @smlkw

phpGeeksJunior
phpGeeksJunior
980 участник(ов)

Группа для новичков. Не стесняйтесь задавать вопросы по php. Не флудить!!!! Правила и полезные ссылки https://gist.github.com/exileed/a53dd0617b35a705ff44b38c8028e6a5 Бест от пхпгикс https://t.me/best_of_phpgeeks

phpclub.ru
phpclub.ru
872 участник(ов)

Официальный чат phpclub.ru - остерегайтесь подделок #rules Правила группы - уважайте друг друга. Скриншоты -> ссылками. Код -> pastebin.com. Вакансии строго -> https://goo.gl/4bNxym, в чат ссылку. За рекламу и мат - БАН!

Devall | PHP
Devall | PHP
272 участник(ов)

Пристанище для восходящих звёзд разработки, которые перейдут на более адекватные языки. http://combot.org/chat/-1001014863761 Инвайт: j.mp/devallphp