Создать индекс для оптимизации медленного запроса - PullRequest
1 голос
/ 29 марта 2011

Существует запрос, который занимает слишком много времени в таблице с 250 000 строк.Мне нужно ускорить его:

create table occurrence (
occurrence_id int(11) primary key auto_increment,
client_id varchar(16) not null,
occurrence_cod varchar(50) not null,
entry_date datetime not null,
zone varchar(8) null default null
)
;

insert into occurrence (client_id, occurrence_cod, entry_date, zone)
values
('1116', 'E401', '2011-03-28 18:44', '004'),
('1116', 'R401', '2011-03-28 17:44', '004'),
('1116', 'E401', '2011-03-28 16:44', '004'),
('1338', 'R401', '2011-03-28 14:32', '001')
;

select client_id, occurrence_cod, entry_date, zone
from occurrence o
where
    occurrence_cod = 'E401'
    and
    entry_date = (
        select max(entry_date)
        from occurrence
        where client_id = o.client_id
    )
;
+-----------+----------------+---------------------+------+
| client_id | occurrence_cod | entry_date          | zone |
+-----------+----------------+---------------------+------+
| 1116      | E401           | 2011-03-28 16:44:00 | 004  |
+-----------+----------------+---------------------+------+
1 row in set (0.00 sec)

Структура таблицы из коммерческого приложения и не может быть изменена.

Какой индекс (ы) лучше всего оптимизировать?Или лучший запрос?

РЕДАКТИРОВАТЬ:

Это последнее вхождение кода E401 для каждого клиента и только если последнее вхождение это код.

Ответы [ 6 ]

4 голосов
/ 29 марта 2011

Идеальные индексы для такого запроса:

index #1: [client_id] + [entry_date]
index #2: [occurence_cod] + [entry_date]

Тем не менее, эти индексы могут быть упрощены, если случится, что данные имеют некоторые характеристики. Это сэкономит файловое пространство, а также время обновления данных (вставка / удаление / обновление).

Если для каждого [client_id] редко встречается более одной записи «вхождения», индекс № 1 может быть только [client_id].

Точно так же, если для каждого [occurence_cod] редко бывает более одной записи «вхождения», индекс № 1 может быть только [occurence_cod].

Может быть более полезно превратить индекс # 2 в [entry_date] + [occurence_cod]. Это позволит вам использовать индекс для критериев, которые указаны только в [entry_date].

С уважением,

1 голос
/ 29 марта 2011
select 
  a.client_id, 
  a.occurrence_cod, 
  a.entry_date, 
  a.zone
from occurrence a 
  inner join (
    select client_id, occurence_cod, max(entry_date) as entry_date 
    from occurence
  ) as b
on 
  a.client_id = b.client_id and 
  a.occurence_cod = b.occurence_cod and 
  a.entry_date = b.entry_date

where
    a.occurrence_cod = 'E401'

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

1 голос
/ 29 марта 2011

Я бы переписал запрос:

select client_id, occurrence_cod, max(entry_date), zone
from occurrence 
group by client_id, occurrence_cod, zone;

(при условии, что остальные строки действительно идентичны, а дата ввода - единственное, что изменяется).

1 голос
/ 29 марта 2011

Если вы по-настоящему не пытаетесь получить строку с максимальной датой, если и только если совпадает с origince_cod, это должно работать:

select client_id, occurrence_cod, entry_date, zone 
from occurrence o 
where occurrence_cod = 'E401'
ORDER BY entry_date DESC
LIMIT 1;

Будет возвращена самая последняя строка с вхождением_cod = 'E401«

0 голосов
/ 29 марта 2011

Попробуйте, если другие подходы недоступны.

  1. создайте новую таблицу: last_occurrence.
  2. Каждый раз, когда пользователь встречался , обновите соответствующую строку в этомТаблица last_occurrence.

. Для этого вам просто нужно использовать следующий sql:)

select * from last_occurrence

0 голосов
/ 29 марта 2011

Вы пытались поставить индекс на occurrence_cod?

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