2015-03-27 6 views
1

Я читал эту статью - NOT IN vs. NOT EXISTS vs. LEFT JOIN/IS NULL: MySQL at EXPLAIN EXTENDED; Я работаю с существующим дизайном.Оптимизация подзапроса

Я хочу, чтобы иметь возможность выбирать все идентификаторы от table a, которых нет в table b.

Я использую этот запрос:

SELECT a.* FROM `orders` a LEFT JOIN `orders_corrected` b ON 
a.`order_id`=b.`order_id` WHERE b.`order_id` IS NULL; 

Table a содержит более 900K записей, и Table b содержит более 200К и растет.

Вышеприведенный запрос занимает около 7-8 минут.

Я также пробовал использовать NOT IN, что тоже медленно.

order_id столбец NOT NULL и UNIQUE индексирован.

Выход explain:

*************************** 1. row *************************** 
id: 1 
select_type: SIMPLE 
table: a 
type: ALL 
possible_keys: NULL 
key: NULL 
key_len: NULL 
ref: NULL 
rows: 595783 
Extra: NULL 
*************************** 2. row *************************** 
id: 1 
select_type: SIMPLE 
table: b 
type: eq_ref 
possible_keys: PRIMARY,order_id_UNIQUE,ix_order_id 
key: PRIMARY 
key_len: 152 
ref: func 
rows: 1 
Extra: Using where; Not exists; Using index 

Любая помощь будет большим.

+0

Поскольку вы выбираете практически все (без фильтров), вы не можете так много сделать. Один из способов его ускорения состоит в том, чтобы сохранить столбец count в таблице заказов, чтобы увидеть, сколько исправленных заказов есть, что может дать вам простой фильтр. – Wolph

+0

@Wolph Это мое последнее средство. Чтобы добавить столбец в таблицу 'a'. Я делаю 'a. *' Потому что все данные необходимы. Я тоже пытался сделать «LIMIT 5». Не очень помогает .. –

ответ

1

То, что я хочу, чтобы иметь возможность выбрать все идентификаторы из таблицы A, которые не находятся в таблице б

Используйте коррелированный подзапрос в ИНЕКЕ включая индексированный столбец. Например:

SELECT U.Id 
FROM Users U 
WHERE (SELECT Count(Ph.UserId) FROM PostHistory Ph WHERE Ph.UserId = U.Id) = 0 

Список литературы

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