Ich habe 2 Tabellen. Von diesen zwei Tabellen versuche ich, Datensätze in eine dritte Tabelle einzufügen, die eine Auswahlabfrage mit Join verwendet. Allerdings habe ich festgestellt, dass Abfrage mit Join keine Indizes verwenden und viel Zeit braucht, daher ist die Einfügung sehr langsam.
Ich habe versucht, mehrere Indizes zu erstellen, wie in einigen Posts vorgeschlagen, aber nicht in Anspruch genommen.
MySQL with JOIN not using index
MySQL query with JOIN not using INDEXWählen Sie Spalten aus Tabelle1 Join Tabelle2, sehr lange dauern
Hier sind meine Tabellen Struktur:
CREATE TABLE master_table (
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
field1 VARCHAR(50) DEFAULT NULL,
field2 VARCHAR(50) DEFAULT NULL,
field3 VARCHAR(50) DEFAULT NULL,
field4 VARCHAR(50) DEFAULT NULL,
PRIMARY KEY (id),
KEY mt_field1_index (field1)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
CREATE TABLE child_table (
c_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
m_id BIGINT(20) UNSIGNED NOT NULL ,
group_id BIGINT(20) UNSIGNED NOT NULL ,
status ENUM('Status1','Status2','Status3') NOT NULL,
job_id VARCHAR(50) DEFAULT NULL,
PRIMARY KEY (c_id),
UNIQUE KEY ct_mid_gid (m_id,group_id),
KEY Index_ct_status (status),
KEY index_ct_jobid (job_id),
KEY index_ct_mid (m_id),
KEY index_ct_cid_sts_tsk (group_id,status,job_id)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
Abfrage:
SELECT m.id
, NULLIF(TRIM(m.field1),'')
FROM master_table m
JOIN child_table c
ON m.id = c.m_id
WHERE c.group_id = 2
AND c.status = 'Status3'
AND c.job_id = 0
ORDER
BY m.id
LIMIT 0, 1000;
Erklären:
+-------+-------------+-------+------------+----------+------------------------------------------------------------------------------+-----------------+---------+--------------+-------+----------+------------------------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+-------+-------------+-------+------------+----------+------------------------------------------------------------------------------+-----------------+---------+--------------+-------+----------+------------------------------------------------+
| 1 | SIMPLE | c | (NULL) | ref | ct_mid_gid,Index_ct_status,index_ct_jobid,index_ct_mid,index_ct_cid_sts_tsk | Index_ct_status | 1 | const | 65689 | 0.00 | Using where; Using temporary; Using filesort |
| 1 | SIMPLE | m | (NULL) | eq_ref | PRIMARY | PRIMARY | 8 | r_n_d.c.m_id | 1 | 100.00 | (NULL) |
+-------+-------------+-------+------------+----------+------------------------------------------------------------------------------+-----------------+---------+--------------+-------+----------+------------------------------------------------+
Danke für die ausführliche Antwort. Sobald ich 'c.m_id' anstelle von m.id in der order by-Klausel verwendet habe, hat es die Verwendung von filesort und temporary gestoppt und beim Hinzufügen des vorgeschlagenen Indexes hat es begonnen, index with where zu verwenden. Obwohl ich mich immer noch frage, ob ich etwas wie m.field1 = 'xyz' in where-Klausel zusammen mit der aktuellen Bedingung hatte, was hätte ich für order by clause verwenden sollen. Ich meine, wann c.m_id zu verwenden und wann m.id – money
Und wenn ich nach der Spalte sortieren muss, die nur in 'master_table' existiert. So etwas wie 'order by m.field1, c.m_id' – money
In einigen Situationen würde der Optimizer bemerken, dass' c.m_id' dasselbe ist wie 'm.id', aber in diesem Fall nicht. –