DB专题-慢查询优化之回表优化-mysql5.7-达梦dm7

回表优化-mysql&dm7测试分析

  • 回表说明
    • 一、mysql回表优化测试
      • 1.1 测试-数据初始化
      • 1.2 测试分析
    • 二、dm7回表优化测试
      • 2.1 测试-数据初始化
      • 2.2 测试分析
    • 三、测试总结

回表说明

通过索引访问得到表的ROWID,然后根据这些ROWID再去访问表中数据行,就称为回表。Oracle如果执行计划里出现table access by rowid,mysql5.6及以上出现Using MRR就说明要回表。
减少回表次数将提高SQL查询性能。

一、mysql回表优化测试

1.1 测试-数据初始化

1、 定义测试表:
CREATE TABLE test (id BIGINT(20) UNSIGNED AUTO_INCREMENT PRIMARY KEY ,
val INT(10) UNSIGNED NOT NULL DEFAULT 0,
source INT(10) UNSIGNED NOT NULL DEFAULT 0
);
CREATE INDEX test_val_index ON test(val ASC);

2、 注入500百万条随机测试数据:
DROP PROCEDURE IF EXISTS twhile;
DROP PROCEDURE IF EXISTS tcountinsert;

DELIMITER //
CREATE PROCEDURE twhile(IN total INT)
BEGIN
DECLARE i INT;
SET i = 0;
WHILE i INSERT INTO test (val,source) VALUES (FLOOR(RAND() * 1000),FLOOR(RAND() * 10000));
SET i = i+1;
END WHILE;
COMMIT;
END
//
DELIMITER ;

DELIMITER //
CREATE PROCEDURE tcountinsert(IN pageCount INT,IN allCount INT)
BEGIN
DECLARE i INT;
SET i = 0;
WHILE i CALL twhile(pageCount);
SET i = i+1;
END WHILE;
END
//
DELIMITER ;

CALL tcountinsert(10000,500);

DB专题-慢查询优化之回表优化-mysql5.7-达梦dm7_第1张图片
初始化数据,执行时间26分钟6秒;

1.2 测试分析

1、 查询val>500,从20万开始的5条数据,sql如下:

SELECT * FROM test WHERE val>500 LIMIT 200000,5;
DB专题-慢查询优化之回表优化-mysql5.7-达梦dm7_第2张图片

       执行时间:4.39秒

Sql解析:
在这里插入图片描述

       使用了val上的范围索引,并使用了MRR策略的回表查询。

2、 回表优化后sql如下:

SELECT * FROM test a INNER JOIN (SELECT id FROM test WHERE val>500 LIMIT 200000,5) b ON a.id=b.id;
DB专题-慢查询优化之回表优化-mysql5.7-达梦dm7_第3张图片
执行时间:0.17秒
Sql解析:

在这里插入图片描述

使用了val上的范围索引,并使用了Using where策略,避免了回表查询。

3、 优化后查询时间提升26倍。

二、dm7回表优化测试

2.1 测试-数据初始化

由于达梦dm7在字段较少时,减少回表的优化体现不明显,因此多加入10个字段(t1~t7)
create tablespace test5 datafile ‘/dm7/data/DAMENG/test5_01.dbf’ size 1024;
create user test5 identified by dameng123 default tablespace test5;

CREATE TABLE test5.test (id int PRIMARY KEY identity(1,1),
val int NOT NULL DEFAULT 0,
source int NOT NULL DEFAULT 0,
t1 int NOT NULL DEFAULT 0,
t2 int NOT NULL DEFAULT 0,
t3 int NOT NULL DEFAULT 0,
t4 int NOT NULL DEFAULT 0,
t5 int NOT NULL DEFAULT 0,
t6 int NOT NULL DEFAULT 0,
t7 int NOT NULL DEFAULT 0,
t8 int NOT NULL DEFAULT 0,
t9 int NOT NULL DEFAULT 0,
t10 int NOT NULL DEFAULT 0
);
CREATE INDEX test5.test_val_index ON test5.test(val ASC);

– 创建存储过程twhile,针对单次插入
CREATE PROCEDURE TEST5.TWHILE(TOTAL IN INT) as
BEGIN
declare
I INT;
begin
for I in 1…TOTAL loop
INSERT INTO test5.test (val,source,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10) VALUES (FLOOR(RAND() * 1000),FLOOR(RAND() * 10000),
FLOOR(RAND() * 100),FLOOR(RAND() * 100),FLOOR(RAND() * 100),FLOOR(RAND() * 100),FLOOR(RAND() * 100),FLOOR(RAND() * 100),FLOOR(RAND() * 100),FLOOR(RAND() * 100)
,FLOOR(RAND() * 100),FLOOR(RAND() * 100));
end loop;
COMMIT;
end;
END;

– 创建存储过程tCountInsert,针对单次插入,pageInsert每次事务插入量,allIndex插入总次数
CREATE or replace PROCEDURE TEST5.TCOUNTINSERT(PAGEINSERT IN INT,ALLINDEX IN INT) as
BEGIN
declare
I INT;
SQLTEXT varchar2(100);
begin
for I in 1…ALLINDEX loop
SQLTEXT := ‘call TEST5.twhile(’||PAGEINSERT||’)’;
EXECUTE IMMEDIATE SQLTEXT;
end loop;
COMMIT;
dbms_stats.gather_table_stats(‘TEST5’,‘TEST’);–更新统计信息
end;
END;
call TEST5.TCOUNTINSERT(10000,500);

DB专题-慢查询优化之回表优化-mysql5.7-达梦dm7_第4张图片
初始化数据用时1分35秒。

2.2 测试分析

从20万行开始搜索

1、 优化前sql执行结果如下:
DB专题-慢查询优化之回表优化-mysql5.7-达梦dm7_第5张图片

执行时间:30.335毫秒

Sql解析:
DB专题-慢查询优化之回表优化-mysql5.7-达梦dm7_第6张图片

2、 优化后sql执行结果如下:
DB专题-慢查询优化之回表优化-mysql5.7-达梦dm7_第7张图片

Sql解析:

DB专题-慢查询优化之回表优化-mysql5.7-达梦dm7_第8张图片

         执行时间:8.813毫秒

3、优化后执行时间提升3.4倍左右。

三、测试总结

回表查询对mysql性能影响较大,dm7在插入速度,查询速度方面比mysql好太多。Mysql初始化500万条数据要20-30分钟,dm7在1-2分钟左右即可初始化完成。

Mysql优化前执行时间长大4s,优化后也接近200ms,dm7优化前30ms,优化后8ms,差距几十倍。

Dm7在数据字段很少的时候,回表查询对整体查询影响不大,有回表对查询的影响也较低。在数据字段较多时,减少回表查询执行时间也有几倍的提升。

Dm7整体性能比mysql好很多,国产数据库目前dm7是最接近oracle语法的。在其他查询测试结论方面也跟oracle很相近(相关综合性测试也有报告,待有空上传),有些甚至更好一些。目前我司因国产化的要求,也在逐渐开始替换。

你可能感兴趣的:(国产数据库测试分析,数据库,mysql,大数据)