|
|
|
Оптимизация запроса (выборка 1 значения из 4 таблиц)
|
|||
|---|---|---|---|
|
#18+
Здравствуйте! Есть мультирегиональный агрегатор товаров различных продавцов. В БД есть таблица регионов (hdbk_regions), таблица рубрик (hdbk_rubrics), таблица товаров (catalog) и таблица связей фирма-регион (firm_region). Таблица рубрик и таблица регионов - деревья значений (path имеет вид 1/123/458/..) Каждому товару из catalog соответствует строго одна рубрика из hdbk_rubrics, строго конечная в ветке (без детей). Каждому товару из catalog соответствует строго один idFirm (идентификатор продавца, сама таблица продавцов к задаче не относится). Каждому идентификатору idFirm соответствует одна или несколько строк в firm_region. Каждый продавцу(idFirm) может соответствовать firm_region.idRegion как конечный в ветке (без детей), так и промежуточный (с детьми). Каждому идентификатору idRegion соответствует строго одна строка hdbk_regions. Не в каждом регионе есть товары во всех рубриках. Задача: по произвольной паре переменных (конечных или промежуточных в дереве) $idRegion, $idRubric определить, есть ли в БД товары для этой пары. Структура таблиц: hdbk_regions id, parentid, lev, path hdbk_rubrics id, parentid, lev, path catalog id, idFirm, idRegion firm_region id, idFirm, idRegion Мое решение. Пробовал решить десятком разных способов (не шучу!) и с помощью EXIST и с разбором запроса на несколько этапов с промежуточной обработкой в приложении, не могу подобрать универсальный для любой комбинации значений. Самое простое конечно обыкновенный JOIN: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. Работает правильно, но мне не удалось подобрать такую комбинацию индексов, что бы не было полного перебора таблиц catalog или firm_region. А эти таблицы увеличиваются, и ясно что это не приемлемо. Ну и Limit здесь как бы не лимит, в том смысле что запрос выдает конечно единственное значение, но по ощущениям перебор не останавливается после первого найденного результата, а продолжается. Как решить такую задачу наиболее правильно, кто знает?? Может быть есть какой то лучший алгоритм, чем простой join таблиц? ЗЫ Если кто то захочет не просто ответить, а поэкспериментировать на реальных данных, дамп БД выложил сюда http://my-files.ru/p6ueh4 (400 Кб., zip). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.10.2015, 18:22:14 |
|
||
|
Оптимизация запроса (выборка 1 значения из 4 таблиц)
|
|||
|---|---|---|---|
|
#18+
Мне так навскидку кажется, что основные проблемы создают OR-ы в секции отбора. Думаю, можно попробовать их разделить, при этом получится 4 отдельных запроса, которые потом соединяются через UNION ALL. Насколько при этом получится оптимизировать частные запросы для условия с подзапросом - честно говоря, думать лениво, но от функций желательно постараться избавиться, если получится (а мне почему-то кажется, что привести их к виду, когда можно создать подходящий индекс - можно). Остальные два точно оптимизируются прекрасно созданием подходящих индексов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.10.2015, 18:38:34 |
|
||
|
Оптимизация запроса (выборка 1 значения из 4 таблиц)
|
|||
|---|---|---|---|
|
#18+
grecha10 Код: sql 1. Что-то я не улавливаю смысл этого фрагмента. Зачем он, если "Каждому товару из catalog соответствует строго одна рубрика из hdbk_rubrics, строго конечная в ветке (без детей)." ? Почему не написать просто c.idRubric='$idRubric' (а таблицу рубрик вовсе не использовать в запросе) ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.10.2015, 19:13:43 |
|
||
|
|

start [/forum/topic.php?fid=47&fpage=123&tid=1832635]: |
0ms |
get settings: |
8ms |
get forum list: |
21ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
35ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
40ms |
get tp. blocked users: |
1ms |
| others: | 204ms |
| total: | 326ms |

| 0 / 0 |
