mysql объединение по двум индексам занимает много времени! - PullRequest
0 голосов
/ 03 января 2011

Привет всем
У меня есть пользовательский запрос в dripal, этот запрос:

select count(distinct B.src) 
from node A, url_alias B 
where concat('node/',A.nid)= B.src;

сейчас, nid в узле является первичным ключом, и я сделал src индексом в таблице url_alias.после ожидания более минуты я получил это:

+-----------------------+  
| count(distinct B.src) |  
+-----------------------+  
|                325715 |  
+-----------------------+  
1 row in set (1 min 24.37 sec)  

, отметив «объяснить», я получил это:

******************* 1. row ***************************  
           id: 1  
  select_type: SIMPLE  
        table: A  
         type: index  
possible_keys: NULL  
          key: PRIMARY  
      key_len: 4  
          ref: NULL  
         rows: 325716  
        Extra: Using index  
*************************** 2. row ***************************  
           id: 1  
  select_type: SIMPLE  
        table: B  
         type: ALL  
possible_keys: src_language_pid,src  
          key: NULL  
      key_len: NULL  
          ref: NULL  
         rows: 325928  
        Extra: Range checked for each record (index map: 0xC)  
2 rows in set (0.00 sec)  

теперь мой вопрос: почему этот запрос не использовалиндекс src, а как его оптимизировать ??

Спасибо за вашу помощь

Ответы [ 3 ]

1 голос
/ 03 января 2011

COUNT(DISTINCT something) для нетривиальных запросов и, если в подсчитанном выражении не существует уникального индекса, заставит запрос создать уникальный индекс на нем во время выполнения запроса.

Это медленно по своей сути и в большинстве случаев:

  • необязательно - решение: переписать запрос так, чтобы различные не нужны

  • если действительно необходимо использовать уникальные, то все же часто быстрее разбить запрос на две части, одна из которых получит полезные результаты запроса, создающего дубликаты B.src, а другая - не нужно отчетливое

Наконец, научитесь использовать EXPLAIN , чтобы вы могли начать изучать, как выполняются ваши запросы и как их оптимизировать.

1 голос
/ 03 января 2011

Проблема производительности связана с использованием concat Если nid является целым числом, это приводит к большой работе.

Я думаю, вам нужно добавить индексированный столбец nid в url_alias.

К сожалению, ваш стол больше не будет нормализован.

0 голосов
/ 03 января 2011

1) объясните этот запрос, запустите его со счетчиком EXPLAIN SLECT ....

2) попробуйте переместить условие соединения (где) в соединение:

 select count(distinct B.src) from node A inner join url_alias B ON concat('node/',A.nid)=B.src

3) чтобы быть быстрым, индексированная вещь должна быть "concat ('node /', nid)" в таблице узлов.Здесь эта вещь должна быть пересчитана для каждой строки узла.В зависимости от вашей версии MySQL, возможно, вы не сможете создать индекс с выражением (только столбцы).Таким образом, у вас может быть столбец, предназначенный для хранения «concat ('node /', nid)», и вы можете назвать его node_nid и проиндексировать его.И убедитесь, что вы его еще не получили!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...