国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數(shù)據(jù)庫(kù) > MySQL > 正文

讓你腦洞大開的MySQL優(yōu)化技巧

2024-07-24 12:59:34
字體:
供稿:網(wǎng)友

由于分庫(kù)分表的原因,和開發(fā)規(guī)定了不能使用 表表JOIN 語句。因此,我們要將 JOIN 語句的轉(zhuǎn)化成使用 IN 來做。如現(xiàn)在有 表 A(a_id, c_a)c_a有普通索引,表 B(b_id, c_a) 這兩個(gè)表要關(guān)聯(lián), 應(yīng)該轉(zhuǎn)化為以下步驟處理:

先查詢B中的 a_id
SELECT c_a FROM B WHERE xxx;使用 IN 查詢 A 表
SELECT a_id, ... FROM A WHERE c_a IN(在 1 中查出來的 c_a)場(chǎng)景

現(xiàn)在表的數(shù)據(jù)量有 800萬。

一般的使用語句是:

SELECT * FROM A WHERE c_a IN(955555, 955556, 955557, 955558, 955559);

上面語句會(huì)執(zhí)行的很快,知道使用 explain 的都明白這樣一般都是會(huì)使用索引的,并且是所有范圍掃描。

MySQL不會(huì)從 1 開始 掃描 800萬,而是從555555 掃描到 555559(只要掃描5行數(shù)據(jù))。

在一般情況下是沒有什么問題的。但是如果 IN 里面的數(shù)據(jù)是不連續(xù)的就有很大問題了。

創(chuàng)建表結(jié)構(gòu)語句
CREATE TABLE t(    id INT unsigned NOT NULL AUTO_INCREMENT,    cid INT unsigned NOT NULL DEFAULT 0,    c1 VARCHAR(50) NOT NULL DEFAULT '',    c2 VARCHAR(50) NOT NULL DEFAULT '',    c3 VARCHAR(50) NOT NULL DEFAULT '',    c4 VARCHAR(50) NOT NULL DEFAULT '',    c5 VARCHAR(50) NOT NULL DEFAULT '',    c6 VARCHAR(50) NOT NULL DEFAULT '',    PRIMARY KEY(id),    INDEX idx$cid(cid)); INSERT INTO t VALUES(    NULL,    FLOOR(RAND() * 1000000),    REPEAT('a', 50),    REPEAT('a', 50),    REPEAT('a', 50),    REPEAT('a', 50),    REPEAT('a', 50),    REPEAT('a', 50)); -- 重復(fù)執(zhí)行INSERT INTO tSELECT NULL,    FLOOR(RAND() * 1000000),    c1,    c2,    c3,    c4,    c5,    c6FROM t;下面是具體的實(shí)驗(yàn)過程使用IN查詢連續(xù)的數(shù)
SELECT *FROM tWHERE cid IN(955555, 955556, 955557, 955558, 955559);+---------+--------+-----------------------------------| id      | cid    | c1                               +---------+--------+-----------------------------------|  319330 | 955555 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 1885293 | 955555 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| ......| 8733757 | 955559 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| 8796305 | 955559 | aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+---------+--------+-----------------------------------41 rows in set (0.15 sec)使用IN查詢不連續(xù)的數(shù)
SELECT *FROM tWHERE cid IN(1, 5000, 50000, 500000, 955559);+---------+--------+-----------------------------------| id      | cid    | c1                               +---------+--------+-----------------------------------|      1 |  341702 |      1 | aaaaaaaaaaaaaaaaaaaaaaaaa|      1 | 1045176 |      1 | aaaaaaaaaaaaaaaaaaaaaaaaa......| 955559 | 8733757 | 955559 | aaaaaaaaaaaaaaaaaaaaaaaaa| 955559 | 8796305 | 955559 | aaaaaaaaaaaaaaaaaaaaaaaaa+--------+---------+--------+--------------------------41 rows in set (4.34 sec)使用UNION優(yōu)化
SELECT *FROM (    SELECT 1 AS cid UNION ALL    SELECT 5000 UNION ALL    SELECT 50000 UNION ALL    SELECT 500000 UNION ALL    SELECT 955559) AS tmp, tWHERE tmp.cid = t.cid;+---------+--------+-----------------------------------| id      | cid    | c1                               +---------+--------+-----------------------------------|      1 |  341702 |      1 | aaaaaaaaaaaaaaaaaaaaaaaaa|      1 | 1045176 |      1 | aaaaaaaaaaaaaaaaaaaaaaaaa......| 955559 | 8733757 | 955559 | aaaaaaaaaaaaaaaaaaaaaaaaa| 955559 | 8796305 | 955559 | aaaaaaaaaaaaaaaaaaaaaaaaa+--------+---------+--------+--------------------------41 rows in set (0.01 sec)

從上面可以看出上面使用UNION的方法生成一個(gè)臨時(shí)表作為關(guān)聯(lián)的主表。

拓展

要是MySQL有只帶的一個(gè)行轉(zhuǎn)列的函數(shù)那就完美了。這樣我們就可以不用使用UNION了。

SELECT 1, 5000, 50000, 500000, 955559;+---+------+-------+--------+--------+| 1 | 5000 | 50000 | 500000 | 955559 |+---+------+-------+--------+--------+| 1 | 5000 | 50000 | 500000 | 955559 |+---+------+-------+--------+--------+1 row in set (0.00 sec)     變成以下SELECT row_to_col(1, 5000, 50000, 500000, 955559);+--------+|     id |+--------+|      1 ||   5000 ||  50000 || 500000 || 955559 |+--------+

要是能像上面就太棒了簡(jiǎn)直。

本文

免費(fèi)提供最新linux技術(shù)教程書籍,為開源技術(shù)愛好者努力做得更多更好:http://www.linuxprobe.com/


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 太谷县| 汝阳县| 南和县| 家居| 张家港市| 南宁市| 赣榆县| 内乡县| 浦城县| 广河县| 安义县| 永年县| 琼海市| 曲阳县| 定远县| 内江市| 富源县| 柯坪县| 崇文区| 武邑县| 泽库县| 南阳市| 西林县| 开封市| 台安县| 汪清县| 乌鲁木齐市| 阳春市| 平原县| 舟曲县| 卓资县| 潍坊市| 福贡县| 白山市| 绥中县| 玉龙| 武定县| 韩城市| 贡山| 三门峡市| 瑞昌市|