簡體   English   中英

mysql將3個表連接在一起的速度很慢-如何正確索引?

[英]mysql joining 3 tables together is performing slow — how to properly index?

我有3個mysql表,試圖將它們連接在一起。

  1. 快照
  2. snapshots_source
  3. 快照_圖像

快照容器是核心描述。

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 BYLIMIT的大型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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM