Помогите с SQL запросом, как облегчить?

backoff

Client
Регистрация
20.04.2015
Сообщения
6 052
Благодарностей
6 481
Баллы
113
привет.
есть небольшая БД sql +- 60мб, там содержится немного инфы, домены, где размещались ссылки где нет, а так же языки сайтов

вот сам запрос
C#:
SELECT * FROM wp_all_good WHERE STATUS='good2' AND NOT lang = 'ja' AND NOT lang = 'zh' AND not siteuse LIKE '%{-Variable.domain-}%' ORDER BY RAND() LIMIT 1;
запрос сложный по вычислениям
то есть запрос берет домен, язык которого не равен ja и zh и поле "siteuse" не содержит домена который размещается, лимит 1
получается идет большая проверка данных перед взятием нужного домена, который по всем параметрам подходит

можно ли как-то сделать, чтоб нагрузка была меньше?
так как при поточности 5+ потоков, сервак начинает немного апупевать
 

Moonwalker

Client
Регистрация
16.03.2016
Сообщения
1 631
Благодарностей
1 225
Баллы
113
status, lang и siteuse - с индексами же?
Понятно, что вопрос дурацкий, но мало ли ))
Вообще, конечно, LIKE всегда прожорливее. Попробуй сперва понять, по какому полю идет долгая выборка, потом думай, как в этом блоке оптимизировать.
Может, условно, вообще от LIKE уйти. Просто сделать дополнительно отдельное поле с чисто доменом (оставить домен без протокола - типа site.com или sub.site2.ru), и по нему уже искать по точному вхождению, без LIKE.
Плюс есть ощущение, что ORDER BY RAND() может серьезно тормозить процесс (на больших базах), на нем обычно спотыкаются. Гугли по ускорению именно этого момента.
update: Пример решения тормозов ORDER BY RAND().
 
Последнее редактирование:

Midnight

Client
Регистрация
28.02.2016
Сообщения
317
Благодарностей
182
Баллы
43
Условие like сильно тормозит запросы, при этом еще и индексация не работает, насколько помню. От него нужно избавляться в первую очередь. Я бы добавил отдельное поле под домен и сравнивал напрямую. И составной индекс для всего этого добавил, при этом домен поставил бы первым в индексе.
 

backoff

Client
Регистрация
20.04.2015
Сообщения
6 052
Благодарностей
6 481
Баллы
113
status, lang и siteuse - с индексами же?
я не сильно шарю, но строка id есть с индексом, или надо каждое поле индексировать?
то есть бд вот так выглядит
102094

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



ок, в целом ответ понятен, попробую более точно описать задачу, может получится что и придумать

короче говоря суть такая - шаблон расставляет ссылки, тот домен НА который ссылка проставлена успешно, он этот домен добавляет в поле "siteuse" (сайт использован), и когда шаблон берет новый сайт, он не должен брать тот сайт, на который он уже поставил ссылку, поэтому и вписал этот like%
то есть по сути, главная задача не брать один и тот же домен для проставления ссылки, чтоб не было дублей

как это можно попроббовать без лайков обойти?

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

Moonwalker

Client
Регистрация
16.03.2016
Сообщения
1 631
Благодарностей
1 225
Баллы
113
Проставить индексы тем полям, по которым идет выборка. Но в твоем случае с LIKE все равно не особо поможет.
Плюс, как я писал, ORDER BY RAND() серьезную проблему создает.
Поэтому я бы пошел таким путем:
1. Проставить индексы полям status, lang и siteuse (если не стоят).
2. Уйти от LIKE в запросе, пример привели (отдельное поле - тоже с индесом - по которому можно искать без LIKE, либо если у тебя все домены единообразно записаны, можно и по текущему искать)
3. Поправить запрос, чтобы отказаться от ORDER BY RAND(). Ссылку на вариант решения я скинул, но можно поискать другие варианты.


как это сделать?
Ну, в твоем варианте вручную проверить запросы:

SQL:
SELECT * FROM wp_all_good WHERE STATUS='good2' AND NOT lang = 'ja' AND NOT lang = 'zh' AND not siteuse LIKE '%{-Variable.domain-}%' ORDER BY RAND() LIMIT 1;
SELECT * FROM wp_all_good WHERE STATUS='good2' AND NOT lang = 'ja' AND NOT lang = 'zh' ORDER BY RAND() LIMIT 1;
SELECT * FROM wp_all_good WHERE STATUS='good2' AND NOT lang = 'ja' AND NOT lang = 'zh' AND not siteuse LIKE '%{-Variable.domain-}%' LIMIT 1;
И так далее. Отрезай по условию. Условно, ты поймешь, какой кусок тормозит процесс. Туда и копать.
 

Moonwalker

Client
Регистрация
16.03.2016
Сообщения
1 631
Благодарностей
1 225
Баллы
113
тот домен НА который ссылка проставлена успешно, он этот домен добавляет в поле "siteuse" (сайт использован)
Так добавляй домен в едином формате (без протокола и заканчивая зоной, условно - site.ru или site.com), тогда сможешь искать просто как WHERE NOT "site.com", без всяких LIKE.
Но в любом случае, имхо, в рандом упрешься )))

Ну или еще, как вариант, просто в siteuse (не знаю, какой там формат у тебя) или в другое поле ставь 1/0, тогда просто изначально делай выборку по полю WHERE поле=0.
 

Wide

Client
Регистрация
04.02.2013
Сообщения
945
Благодарностей
257
Баллы
63
Но в любом случае, имхо, в рандом упрешься )))
SQL:
LOCK TABLES `product_id` WRITE;
SELECT id FROM product_id ORDER BY id ASC LIMIT 1;
DELETE FROM `product_id` ORDER BY id ASC LIMIT 1;
UNLOCK TABLES;
Вместо удаления можно статус задать например.
 

backoff

Client
Регистрация
20.04.2015
Сообщения
6 052
Благодарностей
6 481
Баллы
113
Так добавляй домен в едином формате (без протокола и заканчивая зоной, условно - site.ru или site.com)
дада, он в таком формате и задается - doamin.zone
так как у меня в это поле "siteuse" записывается несколько доменов, получается что поле записывается списком... надо попробовать без лайка сделать запрос, думаю получится, like добавил чтоб наверняка работал))
типа вот так
C#:
SELECT * FROM wp_all_good WHERE STATUS='good2' AND NOT lang = 'ja' AND NOT lang = 'zh' AND WHERE siteuse != '{-Variable.domain-}' ORDER BY RAND() LIMIT 1;
ну и попробую от рандома уйти

попробую переписать логику...
ну или прям на сай хуйдой конец (не хотелось бы этого делать), но для каждого сайта можно сделать отдельный файл со строками id типа
1
2
3
и тд и брать с удалением, это не кошерно, но будет работать 100%
 

Moonwalker

Client
Регистрация
16.03.2016
Сообщения
1 631
Благодарностей
1 225
Баллы
113
дада, он в таком формате и задается - doamin.zone
так как у меня в это поле "siteuse" записывается несколько доменов, получается что поле записывается списком... надо попробовать без лайка сделать запрос, думаю получится, like добавил чтоб наверняка работал))
типа вот так
C#:
SELECT * FROM wp_all_good WHERE STATUS='good2' AND NOT lang = 'ja' AND NOT lang = 'zh' AND WHERE siteuse != '{-Variable.domain-}' ORDER BY RAND() LIMIT 1;
ну и попробую от рандома уйти

попробую переписать логику...
ну или прям на сай хуйдой конец (не хотелось бы этого делать), но для каждого сайта можно сделать отдельный файл со строками id типа
1
2
3
и тд и брать с удалением, это не кошерно, но будет работать 100%
Не, без лайка в твоем случае не сработает. Я только сейчас понял, что у тебя там разные домены записываются, соответственно, может быть что угодно. Не сработает.
У тебя структурно просто изначально немного неверно организованно =/
Я бы вообще делал две таблицы. В одной - домены, КУДА ставить ссылки. В другой - исключительно проставленные ссылки на доменах. Тогда через join можно было бы нормально работать. Но это вопрос привычки )))
В твоем случае, скорее всего, поможет только простановка индексов и, главное, уход от ORDER BY RAND(). Я ссылку кидал на пример, как запрос переделать. Или другой вариант поищи. Так и спроси у гугла, мол "ORDER BY RAND() тормозит" )))
 

Wide

Client
Регистрация
04.02.2013
Сообщения
945
Благодарностей
257
Баллы
63

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)