SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 03.12.2012 12:13:47

x00xer
Участник
Зарегистрирован: 03.12.2012
Сообщений: 3

Оптимизация запросов

Пытаюсь разобраться с оптимизацией запросов по средством их анализа через explain extended и последующих манипуляций структуры запроса, добавления правильных индексов и т.д.. но не до конца понимая видимо как работает БД у меня не получается найти верный ответ. То что внизу это получилось в результате переписывания запроса и добавления индекса, но результат как мне кажется далеко не оптимальный.

Вот к примеру запрос


SELECT a.status, i.username, DATE_FORMAT( CONCAT( i.birthyear,  '-', i.birthmonth,  '-', i.birthday ) ,  '%Y%m%d000000'  ) AS birthdate, m.service_start AS paid
FROM
ads a
LEFT JOIN i USING (member_id)
LEFT JOIN m USING (ad_id)
WHERE a.status!='99'
ORDER BY paid DESC
 

А вот explain

+----+-------------+-------+--------+---------------+-------------+---------+--------------------+------+----------+----------------------------------------------+
| id | select_type | table | type   | possible_keys | key         | key_len | ref                | rows | filtered | Extra                                        |
+----+-------------+-------+--------+---------------+-------------+---------+--------------------+------+----------+----------------------------------------------+
|  1 | SIMPLE      | a     | ALL    | status        | NULL        | NULL    | NULL               | 2129 |    50.02 | Using where; Using temporary; Using filesort |
|  1 | SIMPLE      | i     | eq_ref | PRIMARY       | PRIMARY     | 4       | cv_est.a.member_id |    1 |   100.00 |                                              |
|  1 | SIMPLE      | m     | ref    | index_ad_id   | index_ad_id | 4       | cv_est.a.ad_id     |  118 |   100.00 |                                              |
+----+-------------+-------+--------+---------------+-------------+---------+--------------------+------+----------+----------------------------------------------+

вот какие ключи есть по А таблице
  PRIMARY KEY (`ad_id`),
  KEY `member_id` (`member_id`),
  KEY `status` (`status`),

вот по I
PRIMARY KEY (`member_id`),
...

а вот по M
  PRIMARY KEY (`id`),
  KEY `member_id` (`member_id`),
  KEY `index_ad_id` (`ad_id`)


... почему индекс status не используется для выборки ? И как избавиться от Using where; Using temporary; Using filesort ? как сделать  третью строчку эксплайна сделать eq_ref а не просто ref ?

Спасибо.

Отредактированно x00xer (03.12.2012 12:16:47)

Неактивен

 

#2 03.12.2012 15:20:12

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5833

Re: Оптимизация запросов

x00xer написал:

... почему индекс status не используется для выборки ?

Условию status!='99' удовлетворяет пол таблицы. Быстрее сделать полный перебор (последовательное чтение), чем скакать по индексу (перемещение головки диска туда-сюда).

x00xer написал:

И как избавиться от Using where; Using temporary; Using filesort ?

Никак.

x00xer написал:

как сделать  третью строчку эксплайна сделать eq_ref а не просто ref ?

Сделать индекс `index_ad_id` (`ad_id`) уникальным.

Неактивен

 

#3 06.12.2012 11:09:35

x00xer
Участник
Зарегистрирован: 03.12.2012
Сообщений: 3

Re: Оптимизация запросов

Спасибо за ответ.

P.S. Странно что не пришло уведомление на почту об ответе в теме

Неактивен

 

#4 06.12.2012 17:48:50

x00xer
Участник
Зарегистрирован: 03.12.2012
Сообщений: 3

Re: Оптимизация запросов

Возник еще один вопрос по оптимизации запросов (его лучше тут оставить ? или создать новую тему ?)

Вот запрос

SELECT
        i.*,
        gu.global_user_id as global_user_id,
        gu.username as username,
        gu.password as password,
        gu.user_type,
        gu.x_home_region,
        i.status as account_status,
        vs.cv_id,
        vs.title,
        vs.lang,
        vs.status
        FROM
        common.global_users gu
        LEFT JOIN common.global_users_perms gup ON (gu.global_user_id=gup.global_user_id)
        LEFT JOIN particular.individuals i ON (gup.parent_id = i.member_id)
        LEFT JOIN particular.vs ON (i.member_id=vs.member_id AND vs.status IN (1,4))
        WHERE
            gup.region = 'est'
            AND gu.user_type=2
            AND ((gu.email='some@e.mail') OR (i.email='some@e.mail') OR (gu.username='some@e.mail'))

        ORDER BY i.status, vs.member_id



Вот explain

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: gu
         type: ref
possible_keys: PRIMARY,username,user,idx_email
          key: user
      key_len: 1
          ref: const
         rows: 763022
     filtered: 100.00
        Extra: Using temporary; Using filesort
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: gup
         type: ref
possible_keys: global_user_id,global_user_id_2
          key: global_user_id
      key_len: 4
          ref: common.gu.global_user_id
         rows: 1
     filtered: 100.00
        Extra: Using where
*************************** 3. row ***************************
           id: 1
  select_type: SIMPLE
        table: i
         type: eq_ref
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 4
          ref: common.gup.parent_id
         rows: 1
     filtered: 100.00
        Extra: Using where
*************************** 4. row ***************************
           id: 1
  select_type: SIMPLE
        table: vs
         type: ref
possible_keys: member_id,status
          key: member_id
      key_len: 4
          ref: particular.i.member_id
         rows: 1
     filtered: 100.00
        Extra:
 



Сами таблицы большие по этому сюда структуру не выкладываю.

В mysql slow query log это выглядит следующим образом

# Query_time: 12.320602  Lock_time: 0.000118 Rows_sent: 1  Rows_examined: 2652082

Есть ли какие-то варианты по ускорению данного запроса ?

P.S. причем vs находится в одной БД остальные таблицы в другой.

Отредактированно x00xer (07.12.2012 11:00:15)

Неактивен

 

#5 10.12.2012 04:51:20

Shopen
Гуру
Откуда: Москва
Зарегистрирован: 22.10.2007
Сообщений: 362

Re: Оптимизация запросов

Структуру лучше выкладывать, потому что без нее остаются вопросы.

SELECT
gu.global_user_id as global_user_id,
gu.username as username,
gu.password as password
...
LEFT JOIN common.global_users_perms gup ON (gu.global_user_id=gup.global_user_id)
 



1. что за странные одноименные алиасы? если такие же поля есть в i.* - то не надо писать i.* - перечислите только нужные поля
2. есть ли индекс по полю gu.global_user_id?

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson