У меня есть система, которая хранит контакты и позволяет их группировать. Эти группы могут быть определены по критериям (все с фамилией «кузнец») или путем явного добавления/исключения людей.оптимизация и масштабирование структуры mysql + запросы для больших групп рассылки
Проблема, с которой я столкнулась, заключается в том, что когда я перечислил группы рассылки, мне нужно подсчитать, сколько контактов в каждом из них. Это число может меняться по мере добавления/удаления контактов из таблицы контактов. На малых групп/количество контактов это прекрасно, однако, используя 50k иш контакты сталкивается с проблемами
Пример запроса Я использую для этого заключается в следующем:
SELECT COUNT(c_id) FROM contacts, mgroups
LEFT JOIN mgroups_explicit ON mg_id = me_mg_id
WHERE mgroups.site_id = '10'
AND mg_id = '20'
AND me_c_id = c_id
AND contacts.site_id = '10'
OR (contacts.site_id = '10' AND (c_tags LIKE '%tag1%')) AND c_id NOT IN
(SELECT mex_c_id FROM mgroups_exclude WHERE c_id = mex_c_id) GROUP BY c_id
В таблице критерии не имеют в этом запросе , поскольку проблема возникает, когда большие группы создаются явно, а не с критериями. Это необходимо, поскольку группы, основанные на критериях, растут или сжимаются «на лету», когда вы изменяете свои контакты, где, как явные, обычно задаются в камне. Поэтому в этом случае, если вы явно добавляете 20k контактов в группу, она добавляет 20k строк в таблицу, помеченную этим mg_id как внешний ключ.
Это в основном требует времени/времени/получает неправильный номер/вообще не работает очень хорошо. Мне нужно либо выяснить более эффективный запрос, либо найти лучший способ сохранить все.
Любые идеи?
5 основных таблиц, которые составляют базу данных
contacts - where the actual contacts reside
Field Type Null Default Comments
c_id int(8) No
site_id int(6) No
c_email varchar(500) No
c_source varchar(255) No
c_subscribed tinyint(1) No 0
c_special tinyint(1) No 0
c_domain text No
c_title varchar(12) No
c_name varchar(128) No
c_surname varchar(128) No
c_company varchar(128) No
c_jtitle text No
c_ad1 text No
c_ad2 text No
c_ad3 text No
c_county varchar(64) No
c_city varchar(128) No
c_postcode varchar(32) No
c_lat varchar(100) No
c_lng varchar(100) No
c_country varchar(64) No
c_tel varchar(20) No
c_mob varchar(20) No
c_dob date No
c_registered datetime No
c_updated datetime No
c_twitter varchar(255) No
c_facebook varchar(255) No
c_tags text No
c_special_1 text No
c_special_2 text No
c_special_3 text No
c_special_4 text No
c_special_5 text No
c_special_6 text No
c_special_7 text No
c_special_8 text No
mgroups - basic mailing group info
Field Type Null Default Comments
mg_id int(8) No
site_id int(6) No
mg_name varchar(255) No
mg_created datetime No
mgroups_criteria - criteria for said mailing groups
Field Type Null Default Comments
mc_id int(8) No
site_id int(6) No
mc_mg_id int(8) No
mc_criteria text No
mgroups_exclude - anyone to exclude from criteria
Field Type Null Default Comments
mex_id int(8) No
site_id int(6) No
mex_c_id int(8) No
mex_mg_id int(8) No
mgroups_explicit - anyone to explicitly add without the use of criteria
Field Type Null Default Comments
me_id int(8) No
site_id int(6) No
me_c_id int(8) No
me_mg_id int(8) No
И в индексирует/объяснить запроса. Должен признаться, индексы не мои сильные стороны, никаких улучшений?
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY mgroups ALL PRIMARY,mg_id NULL NULL NULL 9 Using temporary; Using filesort
1 PRIMARY mgroups_explicit ref me_mg_id me_mg_id 4 engine_4.mgroups.mg_id 8750
1 PRIMARY contacts ALL PRIMARY,c_id NULL NULL NULL 86012 Using where; Using join buffer
2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const table...
Скорее смущает, не так ли. Одним из советов, которые я могу дать сразу, является использование точечной нотации, таким образом, вы можете иметь столбцы с одним и тем же именем в разных таблицах, не опасаясь конфликтов, и их легче читать, поэтому c_email можно было бы называть contact.email или if вы также называете имя таблицы «c», а затем c.email, я знаю, что это не помогает, но это сделает ваши запросы более читабельными. – DeveloperChris
Да, он пытался это сделать, но у меня возникали проблемы с входом в ssh с того места, где я был в то время. Должен был получить эти выходы из phpmyadmin, который, кажется, только делает «вид печати» – Horse
извините неправильно, подумал, что вам нужен приятный вид с таблицами таблиц. согласен с точечной нотацией, мой плохой – Horse