Beste Tweakers,
Voor een autoresponder systeem heb ik de volgende tabellen (deze heb ik iets versimpeld en alleen de relevante kolommen meegenomen voor het overzicht. De autoresponder stuurt automatisch e-mail berichten naar inschrijvingen op basis van de inschrijfdatum (start_responder). Per minuut haal ik met 1 query alle berichten op uit een queue tabel waarin alle berichten staan gequeued voor alle autoresponders. Na een succesvolle verzending verwijder ik deze uit de queue tabel en worden deze elders opgeslagen als verzonden.
De query is echter behoorlijk traag (meer dan 6 seconden) en gebruikt meer dan 100% cpu. Ik kom er echter maar niet uit hoe ik deze query ofwel kan opbreken in meerdere simpele queries, danwel optimaliseren. Hieronder volgt de tabellen structuur en de query die ik daarop loslaat:
autoresponder (+/- 1500 records)
Bevat alle autoresponders
PRIMARY: autoresponderid
autoresponder_message (+/- 5000 records)
Bevat alle berichten die onder een autoresponder vallen. Een autoresponder is dus een verzameling (sequence) van een aantal berichten die opeenvolgend worden verzonden. In de followup kolom staat een interval in minuten. (Bijvoorbeeld, verzend na 15 minuten = 15, verzend na 24 uur = 1440)
PRIMARY: messageid
INDEX: autoresponderid
autoresponder_queue (+/- 370.000 records)
Hierin staan de contacten (inschrijvingen) gelinked aan de autoresponder berichten. Op het moment dat een contact zich inschrijft op een bepaalde mailinglijst worden de id's van autoresponder berichten in deze tabel toegevoegd samen met het contactid.
PRIMARY: queueid
INDEX: (autoresponderid,messageid,contactid)
UNIQUE (messageid,contactid) duplicates
contacts (+/- 2.000.000 records)
Hierin staan de contacten (inschrijvingen). De kolom start_responder bevat een timestamp waarop de autoresponder bepaalt welke berichten moeten worden verzonden. Meestal is dit de inschrijfdatum.
PRIMARY contactid
INDEX (listid,subscribed,start_responder) AS autoresponder
In mysql laat ik de volgende query hierop los:
Een explain van de query krijg ik de volgende resultaten:
De query levert ongeveer tussen 2 en 10 resultaten per minuut op. Op zich logisch want er hoeven niet heelveel berichten steeds verstuurd te worden.
In de explain zie je echter dat hij de indexes niet gebruikt. Wanneer ik force index gebruikt performed de query hetzelfde. Het probleem zit hem met name in dat hij de volledie queue tabel scant op berichten. Op zich geen probleem zou je zeggen, maar dit proces neemt veel tijd in beslag.
Hebben jullie enig idee hoe ik deze procedure kan versimpelen?
Voor een autoresponder systeem heb ik de volgende tabellen (deze heb ik iets versimpeld en alleen de relevante kolommen meegenomen voor het overzicht. De autoresponder stuurt automatisch e-mail berichten naar inschrijvingen op basis van de inschrijfdatum (start_responder). Per minuut haal ik met 1 query alle berichten op uit een queue tabel waarin alle berichten staan gequeued voor alle autoresponders. Na een succesvolle verzending verwijder ik deze uit de queue tabel en worden deze elders opgeslagen als verzonden.
De query is echter behoorlijk traag (meer dan 6 seconden) en gebruikt meer dan 100% cpu. Ik kom er echter maar niet uit hoe ik deze query ofwel kan opbreken in meerdere simpele queries, danwel optimaliseren. Hieronder volgt de tabellen structuur en de query die ik daarop loslaat:
autoresponder (+/- 1500 records)
Bevat alle autoresponders
| autoresponderid | listid | title | created | modified |
PRIMARY: autoresponderid
autoresponder_message (+/- 5000 records)
Bevat alle berichten die onder een autoresponder vallen. Een autoresponder is dus een verzameling (sequence) van een aantal berichten die opeenvolgend worden verzonden. In de followup kolom staat een interval in minuten. (Bijvoorbeeld, verzend na 15 minuten = 15, verzend na 24 uur = 1440)
| messageid | autoresponderid | title | body | followup |
PRIMARY: messageid
INDEX: autoresponderid
autoresponder_queue (+/- 370.000 records)
Hierin staan de contacten (inschrijvingen) gelinked aan de autoresponder berichten. Op het moment dat een contact zich inschrijft op een bepaalde mailinglijst worden de id's van autoresponder berichten in deze tabel toegevoegd samen met het contactid.
| queueid | autoresponderid | messageid | contactid |
PRIMARY: queueid
INDEX: (autoresponderid,messageid,contactid)
UNIQUE (messageid,contactid) duplicates
contacts (+/- 2.000.000 records)
Hierin staan de contacten (inschrijvingen). De kolom start_responder bevat een timestamp waarop de autoresponder bepaalt welke berichten moeten worden verzonden. Meestal is dit de inschrijfdatum.
| contactid | listid | subscribed | name | start_responder |
PRIMARY contactid
INDEX (listid,subscribed,start_responder) AS autoresponder
In mysql laat ik de volgende query hierop los:
SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| SELECT q.*, c.email AS contact_email, c.name AS contact_name, m.messageid, m.subject, m.body FROM autoresponder_queue AS q, contacts AS c, autoresponder_message AS m WHERE q.messageid = m.messageid AND q.contactid = c.contactid AND c.subscribed = 1 AND c.start_responder < DATE_FORMAT(DATE_SUB(NOW(), INTERVAL m.followup MINUTE), '%Y%m%d%H%i%s') |
Een explain van de query krijg ik de volgende resultaten:
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | extra |
| 1 | SIMPLE | q | ALL | duplicates | NULL | NULL | NULL | 368747 | Using where |
| 1 | SIMPLE | m | eq_ref | PRIMARY | PRIMARY | 8 | database.q.messageid | 1 | |
| 1 | SIMPLE | c | eq_ref | PRIMARY | PRIMARY | 4 | database.q.contactid | 1 | Using where |
De query levert ongeveer tussen 2 en 10 resultaten per minuut op. Op zich logisch want er hoeven niet heelveel berichten steeds verstuurd te worden.
In de explain zie je echter dat hij de indexes niet gebruikt. Wanneer ik force index gebruikt performed de query hetzelfde. Het probleem zit hem met name in dat hij de volledie queue tabel scant op berichten. Op zich geen probleem zou je zeggen, maar dit proces neemt veel tijd in beslag.
Hebben jullie enig idee hoe ik deze procedure kan versimpelen?
Zoek je mede papa's om gezellig mee te gamen? kijk op: fathersoftweakers.nl