2015-06-30 2 views
0

Обновление:Mysql optimizaiton: есть ли способ сделать это быстрее?

Спасибо всем. Я обобщу ответы.

Из @Jaydee его ответ успешно уменьшает результат до 0.09 секунд, и он является линейным по отношению к числу в LIMIT.

выберите * от (выберите table1.id в table1_id от table1 где table1.id < 100000 заказ по table1.id предела 1000 по убыванию) t1 внутреннее соединение table2 на t1.table2_id = table2.id покинул присоединиться Таблицу 3 на t1.table3_id = table3.id order by t1.id;

От @Rick James, он упоминает, что это может быть проблемой таблицы 2. Поскольку в моей таблице 2 есть только несколько столбцов, я могу оставить ее и присоединиться к себе, даже на стороне клиента!

Поэтому я удаляю таблицу 2, и это всего лишь 0,02 секунды!

table1. id как table1_id от table1 левый объединенный table3 table1. table3_id = table3. id, где table1. id порядок table1. id Ограничение по убыванию 1000;

Наконец-то я обнаружил, что если я изменю таблицу2 из внутреннего объединения влево, то все боли уйдут, это 0.03s!

table1. id как table1_id от table1 левый объединенный table2 table1. table2_id = table2. id левый объединенный table3 table1. table3_id = table3. id, где table1. id < порядок table1. id Ограничение по убыванию 1000;

Еще раз спасибо за помощь!

==============================

Примечание: Я бегу на встроенном сервере с ограниченным барана (около 1G, достаточно, чтобы разместить все данные на самом деле, 200 000 данных) и использовать SD-карту в качестве хранилища.

выберите table1.id из table1, где идентификатор < 100000 заказ по идентификатору лимита по убыванию 1000;

(0,01 с)

выберите table1.id как table1_id от table1 внутренний объединенный table2 table1. table2_id = table2. id, где table1. id < порядок table1. id Ограничение по убыванию 1000;

(0.40s)

выберите table1. id как table1_id от table1 внутренний объединенный table2 table1. table2_id = table2. id, где table1. id < порядок table1. id Ограничение по убыванию 1000;

(0,01 с)

выберите table1. id как table1_id от table1 внутренний объединенный table2 table1. table2_id = table2. id левый объединенный table3 table1. table3_id = table3. id, где table1. id < порядок table1. id Ограничение по убыванию 1000;

(2.31s)

выберите table1. id как table1_id от table1 внутренний объединенный table2 table1. table2_id = table2. id левый объединенный table3 table1. table3_id = table3. id, где table1. id < table1. id Ограничение по убыванию 1000;

(0.03s)


Как комментарий предложил, я объяснить, но я не очень понимаю, что это объясняет слово. Пожалуйста, помогите мне проверить. Ниже приведены самые длинные 2.31s.

+----+-------------+----------------------+--------+-------------------------------------------------------------------+---------------------------------------+---------+---------------------------------------------+-------+----------------------------------------------+ 
| id | select_type | table    | type | possible_keys              | key         | key_len | ref           | rows | Extra          | 
+----+-------------+----------------------+--------+-------------------------------------------------------------------+---------------------------------------+---------+---------------------------------------------+-------+----------------------------------------------+ 
| 1 | SIMPLE  | table2    | index | PRIMARY,table2_id_index           | table1_id_index      | 4  | NULL          |  1 | Using index; Using temporary; Using filesort | 
| 1 | SIMPLE  | table1    | ref | PRIMARY,table1_table2_id_foreign,table1_id_index     | table1_table2_id_foreign    | 4  | videocap.table2.id       | 27222 | Using where         | 
| 1 | SIMPLE  | table3    | eq_ref | PRIMARY               | PRIMARY        | 4  | videocap.table1.table3_id     |  1 | Using index         | 
+----+-------------+----------------------+--------+-------------------------------------------------------------------+---------------------------------------+---------+---------------------------------------------+-------+----------------------------------------------+ 

Результаты по убыванию таблице

Table1:

+-------------------------+------------------+------+-----+---------------------+----------------+ 
| Field     | Type    | Null | Key | Default    | Extra   | 
+-------------------------+------------------+------+-----+---------------------+----------------+ 
| id      | int(10) unsigned | NO | PRI | NULL    | auto_increment | 
| table2_id  | int(10) unsigned | NO | MUL | NULL    |    | 
| table3_id | int(10) unsigned | NO | MUL | 0     |    | 
| created_at    | timestamp  | NO |  | 0000-00-00 00:00:00 |    | 
| updated_at    | timestamp  | NO |  | 0000-00-00 00:00:00 |    | 
+-------------------------+------------------+------+-----+---------------------+----------------+ 

table2:

+-----------------+------------------+------+-----+---------------------+----------------+ 
| Field   | Type    | Null | Key | Default    | Extra   | 
+-----------------+------------------+------+-----+---------------------+----------------+ 
| id    | int(10) unsigned | NO | PRI | NULL    | auto_increment | 
| created_at  | timestamp  | NO |  | 0000-00-00 00:00:00 |    | 
| updated_at  | timestamp  | NO |  | 0000-00-00 00:00:00 |    | 
+-----------------+------------------+------+-----+---------------------+----------------+ 

Table3:

+---------------------------+------------------+------+-----+---------------------+----------------+ 
| Field      | Type    | Null | Key | Default    | Extra   | 
+---------------------------+------------------+------+-----+---------------------+----------------+ 
| id      | int(10) unsigned | NO | PRI | NULL    | auto_increment | 
| created_at    | timestamp  | NO |  | 0000-00-00 00:00:00 |    | 
| updated_at    | timestamp  | NO |  | 0000-00-00 00:00:00 |    | 
+---------------------------+------------------+------+-----+---------------------+----------------+ 
+0

Что объясняет «select select» для всех медленных запросов? И индексируются ли присоединенные ключи? –

+0

У вас есть указатель на 'table1.id'? – Jaydee

+0

table1.id, table2.id, table3.id являются первичным ключом. table1.table2_id, table1.table3_id - нормальный индекс (mul из desc table1). – user534498

ответ

1

Похоже, что таблица2 имеет 1 ряд. Это верно? Сколько строк в каждой таблице?

С помощью всего лишь 1 строки в таблице2 оптимизатор решил решить, с чего начать.

Во всех случаях, PRIMARY KEY(id), особенно если вы используете InnoDB, является оптимальным для

where  table1.id < $number 
    order by table1.id desc 

Однако, если большая часть таблицы имеет идентификатор < 100000, оптимизатор может (ошибочно) решили сделать сканирование таблицы (поскольку оно не учитывало LIMIT). Какую версию ты используешь? 5.6 имеет некоторые улучшения в этой области.

Имейте в виду, что есть миллионы вариантов запросов. Хотя я ценю вашу попытку изолировать важные части запроса; вы можете обнаружить, что применение любого ответа к «реальному» запросу может поразить некоторые другие икоты.

+0

Спасибо. В таблице 1 в настоящее время только 1 строка, но будет более поздней (будет не так уж много), в противном случае нет смысла использовать таблицу 2. Я понимаю, что я перемещаю таблицу 2, и это намного быстрее. Благодарю. – user534498

2

Как это работает? (Исправлены)

select * 
    from 
     (SELECT table1.id as table1_id 
      from table1 
      where table1.id < 100000 
      order by table1.id desc 
      limit 1000 
    ) t1 
    inner join table2 on t1.table2_id = table2.id 
    left join table3 on t1.table3_id = table3.id 
    order by t1.id; 
+0

Да, это уменьшает до 0.09s и линейно соответствует LIMIT. Если я уменьшу значение LIMIT до 100, это будет 0,01 секунды. Благодарю. – user534498

+0

Да, подвыбор минимизирует количество строк, которые соединяются. – Jaydee

Смежные вопросы