медленный подсчет mysql из-за выбора - PullRequest
0 голосов
/ 12 января 2011

как сделать этот оператор выбора быстрее? первое левое соединение с подвыбором делает его медленнее ...

mysql>   SELECT COUNT(DISTINCT w1.id) AS AMOUNT FROM tblWerbemittel w1
    JOIN tblVorgang v1 ON w1.object_group = v1.werbemittel_id
    INNER JOIN ( SELECT wmax.object_group, MAX( wmax.object_revision ) wmaxobjrev FROM tblWerbemittel wmax GROUP BY wmax.object_group ) AS wmaxselect ON w1.object_group = wmaxselect.object_group AND w1.object_revision = wmaxselect.wmaxobjrev
    LEFT JOIN ( SELECT vmax.object_group, MAX( vmax.object_revision ) vmaxobjrev FROM tblVorgang vmax GROUP BY vmax.object_group ) AS vmaxselect ON v1.object_group = vmaxselect.object_group AND v1.object_revision = vmaxselect.vmaxobjrev
    LEFT JOIN tblWerbemittel_has_tblAngebot wha ON wha.werbemittel_id = w1.object_group
    LEFT JOIN tblAngebot ta ON ta.id = wha.angebot_id
    LEFT JOIN tblLieferanten tl ON tl.id = ta.lieferant_id AND wha.zuschlag = (SELECT MAX(zuschlag) FROM tblWerbemittel_has_tblAngebot WHERE werbemittel_id = w1.object_group)
    WHERE w1.flags =0 AND v1.flags=0;

        +--------+
        | AMOUNT |
        +--------+
        |   1982 |
        +--------+
        1 row in set (1.30 sec)

Некоторые индексы уже установлены, и, как показывает EXPLAIN, они были использованы.

+----+--------------------+-------------------------------+--------+----------------------------------------+----------------------+---------+-----------------------------------------------+------+----------------------------------------------+
| id | select_type        | table                         | type   | possible_keys                          | key                  | key_len | ref                                           | rows | Extra                                        |
+----+--------------------+-------------------------------+--------+----------------------------------------+----------------------+---------+-----------------------------------------------+------+----------------------------------------------+
|  1 | PRIMARY            | <derived2>                    | ALL    | NULL                                   | NULL                 | NULL    | NULL                                          | 2072 |                                              |
|  1 | PRIMARY            | v1                            | ref    | werbemittel_group,werbemittel_id_index | werbemittel_group    | 4       | wmaxselect.object_group                       |    2 | Using where                                  |
|  1 | PRIMARY            | <derived3>                    | ALL    | NULL                                   | NULL                 | NULL    | NULL                                          | 3376 |                                              |
|  1 | PRIMARY            | w1                            | eq_ref | object_revision,or_og_index            | object_revision      | 8       | wmaxselect.wmaxobjrev,wmaxselect.object_group |    1 | Using where                                  |
|  1 | PRIMARY            | wha                           | ref    | PRIMARY,werbemittel_id_index           | werbemittel_id_index | 4       | dpd.w1.object_group                           |    1 |                                              |
|  1 | PRIMARY            | ta                            | eq_ref | PRIMARY                                | PRIMARY              | 4       | dpd.wha.angebot_id                            |    1 |                                              |
|  1 | PRIMARY            | tl                            | eq_ref | PRIMARY                                | PRIMARY              | 4       | dpd.ta.lieferant_id                           |    1 | Using index                                  |
|  4 | DEPENDENT SUBQUERY | tblWerbemittel_has_tblAngebot | ref    | PRIMARY,werbemittel_id_index           | werbemittel_id_index | 4       | dpd.w1.object_group                           |    1 |                                              |
|  3 | DERIVED            | vmax                          | index  | NULL                                   | object_revision_uq   | 8       | NULL                                          | 4668 | Using index; Using temporary; Using filesort |
|  2 | DERIVED            | wmax                          | range  | NULL                                   | or_og_index          | 4       | NULL                                          | 2168 | Using index for group-by                     |
+----+--------------------+-------------------------------+--------+----------------------------------------+----------------------+---------+-----------------------------------------------+------+----------------------------------------------+
10 rows in set (0.01 sec)

Основная проблема, хотя приведенное выше утверждение занимает около 2 секунд, по-видимому, это подвыбор, когда индекс не может быть использован. Как написать заявление еще быстрее?

Спасибо за помощь. MT

Ответы [ 2 ]

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

У вас есть следующие индексы?

for tblWerbemittel - object_group, object_revision
for tblVorgang - object_group, object_revision
for tblWerbemittel_has_tblAngebot - werbemittel_id, zuschlag

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

ПРАВИТЬ

Можете ли вы попробовать эти два запроса и посмотреть, быстро ли они работают?

SELECT  w1.id AS AMOUNT 
FROM    tblWerbemittel w1 INNER JOIN 
        (SELECT     wmax.object_group, 
                    MAX( wmax.object_revision ) AS wmaxobjrev 
        FROM        tblWerbemittel AS wmax 
        GROUP BY wmax.object_group ) AS wmaxselect ON   w1.object_group = wmaxselect.object_group AND 
                                                        w1.object_revision = wmaxselect.wmaxobjrev      
WHERE   w1.flags = 0 

SELECT  v1.werbemittel_id 
FROM    tblVorgang v1 LEFT JOIN
        (SELECT     vmax.object_group, 
                    MAX( vmax.object_revision ) AS vmaxobjrev 
        FROM        tblVorgang AS vmax 
        GROUP BY    vmax.object_group ) AS  vmaxselect ON v1.object_group = vmaxselect.object_group AND 
                                            v1.object_revision = vmaxselect.vmaxobjrev LEFT JOIN 
WHERE   v1.flags = 0
0 голосов
/ 12 января 2011

Хотя я считаю, что у меня недостаточно данных для обеспечения 100% правильного ответа, но я могу добавить несколько советов.

Прежде всего, MYSQL глупо.Имейте это в виду и всегда переставляйте свои запросы так, чтобы большинство данных исключалось в начале.Например, если при последнем объединении количество результатов уменьшилось с 10 000 до 2 000, а у других нет, попробуйте поменять их местами, чтобы каждое последующее объединение работало с наименьшим возможным подмножеством данных.предложение WHERE.

Кроме того, объединения, как правило, медленнее, чем подзапросы.Я не знаю, соблюдаю ли я это правило или просто что-то в моем случае, но вы всегда можете попытаться заменить объединение или два подзапросом.

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

...