2013-09-13 3 views
0
account 
act_id | act_name | grp_id | grp_id_2 
2  | test  |  4 | 10 

promotion 
pml_id | act_id | grp_id 
2  | 2  | null 
3  | null  | 4 
4  | null  | 10 

У меня есть две таблицы, показанные выше (обрезанные). У учетной записи около 15000 записей, продвижение около 20000.Проблемы с воспроизведением MYSql

Клиент в основном хочет, чтобы они могли искать имя учетной записи, например «test». И было бы показать акции 2, 3 и 4.

Promotion 3 будет показывать, потому что счет 'тест' имеет grp_id = 4.

Promotion 4 будет показывать, потому что счет 'тест' имеет grp_id_2 = 10.

первоначально я сделал это с парой объединений

SELECT pml_id FROM promotion 
    LEFT JOIN account AS account1 ON promotion.act_id = account1.act_id 
    LEFT JOIN account AS account2 ON promotion.grp_id = account2.grp_id 
    LEFT JOIN account AS account3 ON promotion.grp_id = account3.grp_id_2 
WHERE account1.act_name LIKE 'test%' or account2.act_name LIKE 'test%' 
     or account3.act_name LIKE 'test%' 
GROUP BY pml_id 

проблема с этим это в конечном итоге занимает много времени, когда я начал того, чтобы присоединиться к 5 раз к столу счета. Это также дало мне около 10000000 записей (без группы). В большинстве рекламных акций используется grp_id, редко используется act_id.

Есть ли способ быстро найти столбец act_name в этом сценарии? Не нужно ли так много присоединяться?

У меня есть одиночные индексы act_id, pml_id, grp_id, grp_id_2

Примечание: Это часть запроса, в котором пользователь не может искать по счету. I.E, где предложение не всегда может быть

+0

Возможно ли, чтобы несколько строк в таблице учетных записей имели одно и то же имя act_? –

+0

Да, их нет в данный момент, но они могут в будущем, спасибо, вы просто заставило меня понять что-то еще, они должны нравиться вместо прямого =. Сейчас я сделаю редактирование. – Nicholas

ответ

1

Используйте INNER JOIN вместо того, чтобы избежать сканирования всей таблицы:

SELECT p.pml_id 
FROM account a 
INNER JOIN promotion p 
    ON (p.act_id = a.act_id OR p.grp_id = a.grp_id OR p.grp_id = a.grp_id_2) 
WHERE a.act_name LIKE "test%"; 
0

Это быстрее?

SELECT pml_id FROM promotion p 
    LEFT JOIN account a 
    ON (p.act_id = a.act_id OR p.grp_id = a.grp_id OR p.grp_id = a.grp_id_2) 
WHERE a.act_name LIKE "test%"; 

Попробуйте это, а также, если у вас есть индекс по act_id, это должно быть совсем немного быстрее:

SELECT * FROM promotion p 
LEFT JOIN account a 
    ON (p.act_id = a.act_id OR p.grp_id = a.grp_id OR p.grp_id = a.grp_id_2) 
WHERE a.act_id IN (
    SELECT act_id FROM account WHERE act_name LIKE "test%" 
) 
+0

Я попробовал первый, и все их на одной линии заняло 70 секунд, прежде чем я должен был его убить. Для второго запроса я должен был упомянуть об этом ранее, см. Редактирование вопроса, предложение where может не всегда включаться (так как пользователь не может искать по имени учетной записи) – Nicholas

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