Модераторы: LSD
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите оптимизировать запрос :) 
:(
    Опции темы
Wowa
Дата 24.9.2005, 14:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
Group Icon


Профиль
Группа: Админ
Сообщений: 15017
Регистрация: 14.9.2000
Где: Винград

Репутация: 1
Всего: 290



Помогите оптимизировать запрос smile

Код

SELECT * FROM table
WHERE 
group1 LIKE '%железо%' OR group1 LIKE '%газ%' OR group1 LIKE '%метан%' OR group1 LIKE '%вода%' AND
(group2 LIKE '%железо%' OR group2 LIKE '%газ%' OR group2 LIKE '%метан%' OR group2 LIKE '%вода%' OR group2 IS NULL) AND
(group3 LIKE '%железо%' OR group3 LIKE '%газ%' OR group3 LIKE '%метан%' OR group3 LIKE '%вода%' OR group3 IS NULL)


Поля group1, group2, group3 - имеют тип TEXT.

Нужно, чтобы были найден все записи, если:
- хотя бы одно из ключевых слов присутствует в group1, но group2 и group3 - не заполнены.
- хотя бы одно из ключевых слов присутствует в group1 и хотя бы одно group2, но group3 - пустой поле.
- хотя бы одно из ключевых слов присутствует в group1, хотя бы одно group2 и хотя бы одно в group3
PM WWW   Вверх
Akina
Дата 24.9.2005, 23:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 13
Всего: 454



Цитата(Wowa @ 24.9.2005, 15:19)
Нужно, чтобы были найден все записи, если:

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

Ты чего, сильно спешишь? сформулируй нормально. а лучше ДЛЯ СЕБЯ нарисуй блок-схему проверки условий - глядишь, и проще станет. толко рисуй непременно в бумаге и карандашом. Мне ЭТО часто помогало.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
igon
Дата 25.9.2005, 00:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 327
Регистрация: 30.10.2004

Репутация: 3
Всего: 21



1.Т.к. для выражения типа <условие1>OR<условие2>OR<условие3>OR... <условие2> и последующие не анализируется, если <условие1> верно, предпочтительнее будет
Код

SELECT * FROM table
WHERE 
group1 LIKE '%железо%' OR group1 LIKE '%газ%' OR group1 LIKE '%метан%' OR group1 LIKE '%вода%' AND
(group2 IS NULL OR group2 LIKE '%железо%' OR group2 LIKE '%газ%' OR group2 LIKE '%метан%' OR group2 LIKE '%вода%') AND
(group3 IS NULL OR group3 LIKE '%железо%' OR group3 LIKE '%газ%' OR group3 LIKE '%метан%' OR group3 LIKE '%вода%')

Кроме того, может помочь и анализ частоты встречаемости ключевых слов при формировании запроса: более частое дОлжно ставить на первое место.
2. Если база поддеживает DECODE(), то можно попробовать
Код

SELECT * FROM table
WHERE 
group1||DECODE(group2,NULL,'железо')||DECODE(group3,NULL,'железо') LIKE '%железо%' OR group1||DECODE(group2,NULL,'железо')||DECODE(group3,NULL,'железо') LIKE '%газ%' OR group1||DECODE(group2,NULL,'железо')||DECODE(group3,NULL,'железо') LIKE '%метан%' OR group1||DECODE(group2,NULL,'железо')||DECODE(group2,NULL,'железо') LIKE '%вода%' 

3. Если DECODE() не поддерживается, то
Код

SELECT * FROM table
WHERE 
(group1||group2||group3 LIKE '%железо%' OR 
 group1||group2||group3 LIKE '%газ%' OR  
 group1||group2||group3 LIKE '%метан%' OR 
 group1||group2||group3 LIKE '%вода%' ) OR
(group1 LIKE '%железо%' OR group1 LIKE '%газ%' OR group1 LIKE '%метан%' OR group1 LIKE '%вода%' AND (group2 IS NULL OR group3 IS NULL)) -- В постановке задачи не прописан, но учтен в Select вариант group1='железо', group2=null, group3='газ'. Или этого не может быть? Тогда 
...
(group2 IS NULL OR (group2 IS NOT NULL AND group3 IS NULL))

PS. Конкетенировать лучше через разделитель, скажем, пробел



--------------------
Хотите поговорить об этом?
PM   Вверх
Wowa
Дата 4.12.2005, 11:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
Group Icon


Профиль
Группа: Админ
Сообщений: 15017
Регистрация: 14.9.2000
Где: Винград

Репутация: 1
Всего: 290



Цитата(igon @ 24.9.2005, 22:40)
В постановке задачи не прописан, но учтен в Select вариант group1='железо', group2=null, group3='газ'. Или этого не может быть? Тогда

Если в каком-то из столбцов вообще совпадение не найдено и этот столбец не пустой, то SELECT не должен находить эту строку.
Добавлено @ 11:22
Цитата(Akina @ 24.9.2005, 21:40)
А если ни одно из этих трех условий не выполняется, то можно и не искать все записи? во блин...

Если хотя бы одно условие не выполняется, то SELECT не должен извлекать эту строку из таблицы.
Добавлено @ 11:25
Цитата(igon @ 24.9.2005, 22:40)

SELECT * FROM table
WHERE
(group1||group2||group3 LIKE '%железо%' OR
group1||group2||group3 LIKE '%газ%' OR 
group1||group2||group3 LIKE '%метан%' OR
group1||group2||group3 LIKE '%вода%' ) OR
(group1 LIKE '%железо%' OR group1 LIKE '%газ%' OR group1 LIKE '%метан%' OR group1 LIKE '%вода%' AND (group2 IS NULL OR group3 IS NULL)) -- В постановке задачи не прописан, но учтен в Select вариант group1='железо', group2=null, group3='газ'. Или этого не может быть? Тогда
...
(group2 IS NULL OR (group2 IS NOT NULL AND group3 IS NULL))



Кстати..., насколько сложный/ресурсоемкий запрос у нас получился? В таблице около 1000 000 записей. Три столбца, в каждом примерно по 15 слов - с которыми нужно сравнение проводить.
Нужно находить все записи, не ограничивая их через LIMIT. Т.е. не частями, а сразу все..
Добавлено @ 11:25
база будет - MySQL использоваться.
PM WWW   Вверх
Wowa
Дата 4.12.2005, 11:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
Group Icon


Профиль
Группа: Админ
Сообщений: 15017
Регистрация: 14.9.2000
Где: Винград

Репутация: 1
Всего: 290



Ведь запрос:
Код

SELECT * FROM ibf_posts WHERE post LIKE "%PHP%"

гораздо более легкий, но выполняется на моем домашнем компе аж 40сек!

А такой запрос:
Код

SELECT * FROM ibf_posts WHERE post LIKE "%PHP%" LIMIT 1000

6сек.
Добавлено @ 11:49
Индекс правда отсутствует по столбцу post.
Добавлено @ 11:55
В общем... Похоже, что без LIMIT этот запрос офигенно ресурсоемкий
PM WWW   Вверх
Wowa
Дата 4.12.2005, 14:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
Group Icon


Профиль
Группа: Админ
Сообщений: 15017
Регистрация: 14.9.2000
Где: Винград

Репутация: 1
Всего: 290



У меня появилась другая идея решения этой задачи. Это создать на каждую группу слов по отдельной таблице.

group1
id|slovo

group2
id|slovo

group3
id|slovo



Код

SELECT * FROM group1, group2, group3 WHERE group1.id=group2.id=group3.id
    group1.slovo IN ('$slovo1', '$slovo2', '$slovo3') or group1.slovo IS NULL or
 or group2.slovo IN ('$slovo1', '$slovo2', '$slovo3') or group2.slovo IS NULL or
 or group3.slovo IN ('$slovo1', '$slovo2', '$slovo3') or group3.slovo IS NULL


PM WWW   Вверх
Akina
Дата 4.12.2005, 22:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 13
Всего: 454



Цитата(Wowa @ 24.9.2005, 15:19)
Нужно, чтобы были найден все записи, если:
- хотя бы одно из ключевых слов присутствует в group1, но group2 и group3 - не заполнены.
- хотя бы одно из ключевых слов присутствует в group1 и хотя бы одно group2, но group3 - пустой поле.
- хотя бы одно из ключевых слов присутствует в group1, хотя бы одно group2 и хотя бы одно в group3

Итак - независимо ни от чего хотя бы одно ключевое слово ОБЯЗАНО присуктствовать в поле group1. Если нет - запись не отбирается. Все остальное - дополнения к этому условию.
Посему кажется логичным реализовать вложенность - внутренний запрос отбирает те строки, в коих group1 содержит ключевое слово, а внешний запрос уже накладывает дополнительные условия.
Кроме того "group2 и group3 - не заполнены" - это частный случай "хотя бы одно group2, но group3 - пустой поле" (как я понял). Следовательно, первый вариант отбора можно вообще вычеркнуть - все что он отберет, отберет и второй вариант, а лишние проверки обработку не ускоряют.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Wowa
Дата 4.12.2005, 22:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
Group Icon


Профиль
Группа: Админ
Сообщений: 15017
Регистрация: 14.9.2000
Где: Винград

Репутация: 1
Всего: 290



Цитата(Akina @ 4.12.2005, 20:07)
Следовательно, первый вариант отбора можно вообще вычеркнуть - все что он отберет, отберет и второй вариант, а лишние проверки обработку не ускоряют.

Второй вариант(group2) отберет, но он отберет больше, чем надо. Т.к. какое-то из слов должно встречаться также в group1, ну и в group3 - если оно заполнено.


Цитата(Akina @ 4.12.2005, 20:07)
Итак - независимо ни от чего хотя бы одно ключевое слово ОБЯЗАНО присуктствовать в поле group1. Если нет - запись не отбирается. Все остальное - дополнения к этому условию.

хотя бы одно из слов должно присутствовать во всех столбцах, если они не пусты.
PM WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Общие вопросы по базам данных"
LSD
Zloxa

Данный форум предназначен для обсуждения вопросов о базах данных не попадающих под тематику других форумов:

  • вопросам по СУБД для которых нет отдельных подфорумов
  • вопросам которые затрагивают несколько разных СУБД (например проблема выбора)
  • инструменты для работы с СУБД
  • вопросы проектирования БД
  • теоретически вопросы о СУБД

Данный форум не предназначен для:

  • вопросов о поиске разлиных БД (если не понимаете чем БД отличается от СУБД то: а) вам не сюда; б) Google в помощь)
  • обсуждения проблем с доступом к СУБД из различных ЯП (для этого есть соответсвующие форумы по каждому ЯП)
  • обсуждения проблем с написание SQL запросов, для этого есть форум Составление SQL-запросов
  • просьб о написании курсовой, реферата и т.п., для этого есть Центр помощи или фриланс биржа
  • объявлений о найме специалистов, для этого есть раздел Объявления о найме специалистов

Если вы не соблюдаете эти правила, не удивляйтесь потом не найдя свою тему/сообщение. ;)


Полезные советы:

При написании сообщения постарайтесь дать теме максимально понятное название. В теме максимально подробно опишите проблему. Если применимо укажите: название базы данных и версии (MySQL 4.1, MS SQL Server 2000 и т.п.); используемых язык программирования; способа доступа (ADO, BDE и т.д.); сообщения об ошибках.

Для вставки кода используйте теги [code=sql] [/code].

Литературу по базам данных можно поискать здесь.

Действия модераторов можно обсудить здесь.


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, LSD, Zloxa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | СУБД, общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0557 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.