MySQL - более быстрый метод для этого сложного запроса? - PullRequest
0 голосов
/ 22 ноября 2008

Существует ли менее ресурсоемкий / более быстрый способ выполнения этого запроса (который частично основан на: Этот вопрос StackOverflow ). В настоящее время поиск занимает не более дюжины или около того строк в таблице за 0,008 секунды.

SELECT DISTINCT *
FROM (
(

SELECT DISTINCT ta.auto_id, li.address, li.title, GROUP_CONCAT( ta.tag ) , li.description, li.keyword, li.rating, li.timestamp
FROM tags AS ta
INNER JOIN links AS li ON ta.auto_id = li.auto_id
WHERE ta.user_id =1
AND (
ta.tag LIKE '%query%'
)
OR (
li.keyword LIKE '%query%'
)
GROUP BY li.auto_id
)
UNION DISTINCT (

SELECT DISTINCT auto_id, address, title, '', description, keyword, rating, `timestamp`
FROM links
WHERE user_id =1
AND (
keyword LIKE '%query%'
)
)
) AS total
GROUP BY total.auto_id

Большое спасибо,

Ice

Ответы [ 5 ]

2 голосов
/ 22 ноября 2008

Я надеюсь, что оптимизатор запросов сделает это за вас, но вы можете попробовать выполнить выборку по тегам по user_id перед выполнением объединения на всякий случай в первом подзапросе. Это уменьшит количество строк, к которым вам, вероятно, придется присоединиться. Вы также, вероятно, хотите иметь индексы для auto_id и user_ID.

SELECT DISTINCT *
FROM (
   (SELECT ta.auto_id, li.address, li.title, GROUP_CONCAT( ta.tag ),
           li.description, li.keyword, li.rating, li.timestamp
    FROM (SELECT auto_id, tag FROM tags WHERE user_id = 1) AS ta
         INNER JOIN links AS li ON ta.auto_id = li.auto_id
         WHERE (ta.tag LIKE '%query%') OR (li.keyword LIKE '%query%')
    GROUP BY li.auto_id
   )
   UNION (
       SELECT auto_id, address, title, '', description, keyword, rating, `timestamp`
       FROM links
       WHERE user_id = 1 AND (keyword LIKE '%query%')
   )
) AS total
GROUP BY total.auto_id
1 голос
/ 22 ноября 2008

Тестирование этого на таблицах с десятками строк не обязательно скажет вам, если есть проблема с производительностью. СУБД может использовать разные стратегии в зависимости от размера таблиц.

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

1 голос
/ 22 ноября 2008

Если вы можете использовать формат таблицы MyISAM, попробуйте использовать полнотекстовый индекс и выполнить поиск по ta.tag и li.keyword.

0 голосов
/ 23 ноября 2008

Подстановочные знаки%, вероятно, помешают вашему запросу использовать индексы, особенно ведущие - при поиске «cat%» все еще могут использоваться индексы, но «% cat%» не может. Если ваш набор данных не мал, это, вероятно, смертельно.

Я бы также проверил, вызывает ли у вас логика «ИЛИ» - я не уверен, сможет ли оптимизатор отдельно оптимизировать критерии ключевых слов и тегов. Если не сможет, то сдастся и перебьет его.

Чтобы повторить некоторые другие комментарии:

  • тест с большим набором данных
  • сначала попробуйте компоненты этого запроса (там около трех отдельных запросов), прежде чем пытаться соединить их все вместе.
0 голосов
/ 22 ноября 2008

Трудно быть уверенным без определений таблиц, но вы можете перефразировать запрос как более простое соединение слева от ССЫЛКИ к ТЕГАМ:

select li.auto_id, 
       address, 
       title, 
       group_concat(ta.tag), 
       description,  
       keyword, 
       rating,  
       timestamp 
from links li  
left join tags ta ON ta.auto_id = li.auto_id  
where li.user_id = 1 and ( keyword like '%query%' or ta.tag like '%query%' ) 
group by li.auto_id;

В зависимости от определения таблицы может потребоваться усиление логики, чтобы справиться с пустыми значениями в ключевом слове или в файле ta.tag.

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