[英]mysql joining 3 tables together is performing slow — how to properly index?
我有3個mysql表,試圖將它們連接在一起。
快照容器是核心描述。
snapshots_source與使用snapshot_id作為外部參照的快照是1:1關系
snapshots_image與快照的比例為1:很多。在快照中,可以有很多圖像引用相同的snapshot_id。 snapshot_id記錄可能不存在,但我仍然希望它返回,只要長快照且源找到匹配的記錄即可。
CREATE TABLE `snapshots` (
`snapshot_id` int(11) NOT NULL AUTO_INCREMENT,
`email` varchar(256) COLLATE utf8mb4_unicode_ci NOT NULL,
`seed` varchar(256) COLLATE utf8mb4_unicode_ci NOT NULL,
`date_sent` datetime NOT NULL,
`date_created` datetime NOT NULL,
`date_modified` datetime DEFAULT NULL,
`subject` varchar(1024) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`html` longtext COLLATE utf8mb4_unicode_ci NOT NULL,
`size` int(11) DEFAULT NULL,
`status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '-1= error, 0 = new, 1 = approved, 2 = review ',
`archive` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`snapshot_id`),
KEY `snapshot_id` (`snapshot_id`),
KEY `date_sent` (`date_sent`)
) ENGINE=InnoDB AUTO_INCREMENT=251398 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=COMPACT
CREATE TABLE `snapshots_source` (
`ss_id` int(11) NOT NULL AUTO_INCREMENT,
`snapshot_id` int(11) DEFAULT NULL,
`html` longtext COLLATE utf8mb4_unicode_ci,
PRIMARY KEY (`ss_id`),
UNIQUE KEY `snapshot_id_UNIQUE` (`snapshot_id`)
) ENGINE=InnoDB AUTO_INCREMENT=176129 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=COMPACT
CREATE TABLE `snapshots_images` (
`si_id` int(11) NOT NULL AUTO_INCREMENT,
`snapshot_id` int(11) NOT NULL,
`image` text COLLATE utf8mb4_unicode_ci NOT NULL,
`dimensions` varchar(16) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`si_id`),
KEY `snapshot_id` (`snapshot_id`)
) ENGINE=InnoDB AUTO_INCREMENT=287890 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=COMPACT
這是我的查詢:
SELECT sn.email, sn.date_sent, sn.subject, sh.html, sn.size, si.image, si.dimensions
FROM snapshots sn
INNER JOIN snapshots_source sh ON sh.snapshot_id = sn.snapshot_id
LEFT JOIN snapshots_images si ON sn.snapshot_id = si.snapshot_id
ORDER BY sn.date_sent DESC
LIMIT 10;
我得到以下信息:
id,select_type,table,type,possible_keys,key,key_len,ref,rows,Extra
1,SIMPLE,sn,index,"PRIMARY,snapshot_id",date_sent,5,,1000,
1,SIMPLE,sh,ref,snapshot_id,snapshot_id,5,mockd.sn.snapshot_id,1,
1,SIMPLE,si,ref,snapshot_id,snapshot_id,4,mockd.sn.snapshot_id,1,
看起來像它的索引,但對於1000個結果仍然很慢。 這花費了4.43秒。
我的預期結果。 讓我們從snapshots_images開始。 它包含可以通過snapshot_id索引與快照關聯的任何圖像。
例如:
snapshots_images
================
si_id snapshot_id image dimension
1 1 some_url 100x100
2 1 some_url 100x100
3 2 some_url 100x100
4 4 some_url 100x100
如您在此處所見,缺少快照ID 3,因為快照並不總是具有關聯的映像,但是如果需要,它可以支持多個快照,例如快照1。
snapshots_source
================
ss_id snapshot_id html
1 1 'some html'
2 2 'some html'
3 3 'some html'
4 4 'some html'
5 6 'some html'
如您在此處看到的那樣,這里只能有一個snapshot_id可以關聯回snapshots.snapshot_id。 在這種情況下,snapshot_id對於該表是唯一的。
snapshots
=========
snapshot_id email
1 'some email'
2 'some email'
3 'some email'
4 'some email'
5 'some email'
6 'some email'
我在這里過於簡化,因此示例中未顯示某些字段。 在這種情況下,由於snapshot_id 5在snapshots_source中沒有記錄,因此結果不應該顯示任何帶有snapshot_id 5的記錄。
我的預期結果如下所示:
snapshot_id email html image dimensions
1 'some email' 'some html' 'some url' 100x100
2 'some email' 'some html' 'some url' 100x100
3 'some email' 'some html' null null
4 'some email' 'some html' 'some url' 100x100
6 'some email' 'some html' null null
問題:是否有進一步優化的方法? 預期的查詢可能是大約10,000個結果。 任何幫助,將不勝感激
您的索引看起來很好,如果在某些地方有點多余,我想慢的根源可能是結合了ORDER BY
和LIMIT
的大型TEXT
字段的存在(在對整個結果進行排序之前,它無法減少結果集設置;我希望它會在內部延遲加載與順序無關的較大字段,但可能不會)。
您可能會在以下方面取得一些成功:
SELECT sn.email, sn.date_sent, sn.subject, sh.html, sn.size, si.image, si.dimensions
FROM (
SELECT snapshot_id, email, date_sent, subject, size
FROM snapshots
ORDER BY date_sent DESC
LIMIT 10
) AS sn
LEFT JOIN snapshots_html sh ON sh.snapshot_id = sn.snapshot_id
INNER JOIN snapshots_images si ON sn.snapshot_id = si.snapshot_id
LIMIT 10;
請注意,我LIMIT
ed兩次,因為以后的聯接可能會使結果相乘。 但是,我注意到最后一個聯接是一個內部聯接,因此它實際上也可能減少結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.