我有一张表,我需要在很多不同的表上进行连接。该数据集长达140 000条记录。
示例如下:
SELECT SQL_CALC_FOUND_ROWS e.designation
, e.remark
, e.moment
, e.rpm
, e.cycleK
, c.type
, d.description
, a.PAnr
, b.family
, b.articlenrKronhjul
, b.ratio
, a.oiltype
, a.oiltemp
, a.createdBy
, a.createdDate
FROM testdata_test a
, testdata_gear b
, testdata_damcategory c
, testdata_damage d
, testdata_result e
WHERE a.id = e.test_id
AND e.id = d.result_id
AND a.id = b.test_id
AND c.id = d.category_id
ORDER
BY designation asc
LIMIT 0, 10
平均约1秒,我怎样才能加快速度? 我一直试图在某些列上添加一些索引,但没有太大的改进。
任何人都有任何提示吗?
编辑:
这是我的常规和JSON格式的查询计划:
+----+-------------+-------+------+---------------------------------------------------+--------------------------+---------+----------------+------+----------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------------------------------------------+--------------------------+---------+----------------+------+----------------------------------------------------+
| 1 | SIMPLE | a | ALL | PRIMARY | NULL | NULL | NULL | 10617 | Using where; Using temporary; Using filesort |
| 1 | SIMPLE | b | ref | TestData_gear_2e06cda4 | TestData_gear_2e06cda4 | 5 | webappdev.a.id | 1 | NULL |
| 1 | SIMPLE | e | ref | PRIMARY,TestData_result_2e06cda4 | TestData_result_2e06cda4 | 4 | webappdev.a.id | 5 | NULL |
| 1 | SIMPLE | d | ref | TestData_damage_b583a629,TestData_damage_57f06544 | TestData_damage_57f06544 | 4 | webappdev.e.id | 1 | NULL |
| 1 | SIMPLE | c | ALL | PRIMARY | NULL | NULL | NULL | 4 | Using where; Using join buffer (Block Nested Loop)|
+----+-------------+-------+------+---------------------------------------------------+--------------------------+---------+----------------+-------+---------------------------------------------------+
5 rows in set (0.00 sec)
| {
"query_block": {
"select_id": 1,
"ordering_operation": {
"using_temporary_table": true,
"using_filesort": true,
"nested_loop": [
{
"table": {
"table_name": "a",
"access_type": "ALL",
"possible_keys": [
"PRIMARY"
],
"rows": 10617,
"filtered": 100,
"attached_condition": "(`webappdev`.`a`.`id` is not null)"
}
},
{
"table": {
"table_name": "b",
"access_type": "ref",
"possible_keys": [
"TestData_gear_2e06cda4"
],
"key": "TestData_gear_2e06cda4",
"used_key_parts": [
"test_id"
],
"key_length": "5",
"ref": [
"webappdev.a.id"
],
"rows": 1,
"filtered": 100
}
},
{
"table": {
"table_name": "e",
"access_type": "ref",
"possible_keys": [
"PRIMARY",
"TestData_result_2e06cda4"
],
"key": "TestData_result_2e06cda4",
"used_key_parts": [
"test_id"
],
"key_length": "4",
"ref": [
"webappdev.a.id"
],
"rows": 5,
"filtered": 100
}
},
{
"table": {
"table_name": "d",
"access_type": "ref",
"possible_keys": [
"TestData_damage_b583a629",
"TestData_damage_57f06544"
],
"key": "TestData_damage_57f06544",
"used_key_parts": [
"result_id"
],
"key_length": "4",
"ref": [
"webappdev.e.id"
],
"rows": 1,
"filtered": 100
}
},
{
"table": {
"table_name": "c",
"access_type": "ALL",
"possible_keys": [
"PRIMARY"
],
"rows": 4,
"filtered": 75,
"using_join_buffer": "Block Nested Loop",
"attached_condition": "(`webappdev`.`c`.`id` = `webappdev`.`d`.`cate
gory_id`)"
}
}
]
}
}
} |
以下是我的CREATE TABLES和表格的计数
mysql> SHOW CREATE TABLE testdata_test;
| testdata_test | CREATE TABLE `testdata_test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`PAnr` int(11) NOT NULL,
`projectAcc` varchar(20) DEFAULT NULL,
`reportnr` varchar(20) DEFAULT NULL,
`oiltype` varchar(40) DEFAULT NULL,
`oiltemp` int(11) DEFAULT NULL,
`headline1` varchar(40) DEFAULT NULL,
`headline2` varchar(40) DEFAULT NULL,
`testDescription` longtext,
`TestName` varchar(9) DEFAULT NULL,
`createdBy` varchar(6) NOT NULL,
`createdDate` date NOT NULL,
PRIMARY KEY (`id`),
FULLTEXT KEY `test_index_testdescription` (`testDescription`)
) ENGINE=InnoDB AUTO_INCREMENT=14172 DEFAULT CHARSET=utf8 |
1 row in set (0.00 sec)
mysql> SELECT count(*) FROM testdata_test;
+----------+
| count(*) |
+----------+
| 14161 |
+----------+
1 row in set (0.01 sec)
mysql> SHOW CREATE TABLE testdata_gear;
| testdata_gear | CREATE TABLE `testdata_gear` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`family` varchar(20) NOT NULL,
`articlenrKronhjul` int(11) DEFAULT NULL,
`revisionK` varchar(200) DEFAULT NULL,
`articlenrPinjong` int(11) DEFAULT NULL,
`revisionP` varchar(200) DEFAULT NULL,
`ratio` double DEFAULT NULL,
`geardata` varchar(100) DEFAULT NULL,
`remark` varchar(40) DEFAULT NULL,
`test_id` int(11),
PRIMARY KEY (`id`),
KEY `TestData_gear_2e06cda4` (`test_id`),
CONSTRAINT `TestData_gear_test_id_325c2ab6_fk_TestData_test_id` FOREIGN KEY (`
test_id`) REFERENCES `testdata_test` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=14167 DEFAULT CHARSET=utf8 |
mysql> SELECT count(*) FROM testdata_gear;
+----------+
| count(*) |
+----------+
| 14157 |
+----------+
1 row in set (0.01 sec)
| testdata_result | CREATE TABLE `testdata_result` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`designation` varchar(20) NOT NULL,
`remark` varchar(200) DEFAULT NULL,
`moment` double DEFAULT NULL,
`rpm` int(11) DEFAULT NULL,
`cycleK` int(11) DEFAULT NULL,
`test_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `test_id_result_index` (`test_id`) USING BTREE,
KEY `result_designation_index` (`designation`) USING BTREE,
CONSTRAINT `TestData_result_test_id_5ed0cbc8_fk_TestData_test_id` FOREIGN KEY
(`test_id`) REFERENCES `testdata_test` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=141382 DEFAULT CHARSET=utf8 |
mysql> SELECT count(*) FROM testdata_result;
+----------+
| count(*) |
+----------+
| 141323 |
+----------+
1 row in set (0.03 sec)
mysql> SHOW CREATE TABLE testdata_damage;
| testdata_damage | CREATE TABLE `testdata_damage` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`description` longtext NOT NULL,
`part` varchar(100) DEFAULT NULL,
`timestamp` datetime(6) NOT NULL,
`category_id` int(11),
`result_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `TestData_damage_b583a629` (`category_id`),
KEY `TestData_damage_57f06544` (`result_id`),
FULLTEXT KEY `damage_index_description` (`description`),
CONSTRAINT `TestData_damage_category_id_215346e4_fk_TestData_damcategory_id` F
OREIGN KEY (`category_id`) REFERENCES `testdata_damcategory` (`id`),
CONSTRAINT `TestData_damage_result_id_2fb199b2_fk_TestData_result_id` FOREIGN
KEY (`result_id`) REFERENCES `testdata_result` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=141341 DEFAULT CHARSET=utf8 |
mysql> SELECT count(*) FROM testdata_damage;
+----------+
| count(*) |
+----------+
| 141291 |
+----------+
1 row in set (0.04 sec)
mysql> SHOW CREATE TABLE testdata_damcategory;
| testdata_damcategory | CREATE TABLE `testdata_damcategory` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`type` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 |
mysql> SELECT count(*) FROM testdata_damcategory;
+----------+
| count(*) |
+----------+
| 5 |
+----------+
1 row in set (0.00 sec)
SELECT COUNT(*) FROM (
SELECT e.designation
...
) AS x;
+----------+
| COUNT(*) |
+----------+
| 141298 |
+----------+
1 row in set (2.40 sec)¨
编辑: 用指定的指数解释
| {
"query_block": {
"select_id": 1,
"ordering_operation": {
"using_temporary_table": true,
"using_filesort": true,
"nested_loop": [
{
"table": {
"table_name": "a",
"access_type": "ALL",
"possible_keys": [
"PRIMARY"
],
"rows": 10617,
"filtered": 100,
"attached_condition": "(`webappdev`.`a`.`id` is not null)"
}
},
{
"table": {
"table_name": "b",
"access_type": "ref",
"possible_keys": [
"TestData_gear_2e06cda4",
"test_id_gear_index"
],
"key": "TestData_gear_2e06cda4",
"used_key_parts": [
"test_id"
],
"key_length": "5",
"ref": [
"webappdev.a.id"
],
"rows": 1,
"filtered": 100
}
},
{
"table": {
"table_name": "e",
"access_type": "ref",
"possible_keys": [
"PRIMARY",
"test_id_result_index"
],
"key": "test_id_result_index",
"used_key_parts": [
"test_id"
],
"key_length": "4",
"ref": [
"webappdev.a.id"
],
"rows": 4,
"filtered": 100
}
},
{
"table": {
"table_name": "d",
"access_type": "ref",
"possible_keys": [
"TestData_damage_b583a629",
"TestData_damage_57f06544",
"result_id_damage_index"
],
"key": "TestData_damage_57f06544",
"used_key_parts": [
"result_id"
],
"key_length": "4",
"ref": [
"webappdev.e.id"
],
"rows": 1,
"filtered": 100
}
},
{
"table": {
"table_name": "c",
"access_type": "ALL",
"possible_keys": [
"PRIMARY"
],
"rows": 4,
"filtered": 75,
"using_join_buffer": "Block Nested Loop",
"attached_condition": "(`webappdev`.`c`.`id` = `webappdev`.`d`.`cate
gory_id`)"
}
}
]
}
}
} |
最终更新: 以下是最终完成这一操作的查询,并将查询时间降低到0.1s以下。
SELECT e.designation
, e.remark
, e.moment
, e.rpm
, e.cycleK
, c.type
, d.description
, a.PAnr
, b.family
, b.articlenrKronhjul
, b.ratio
, a.oiltype
, a.oiltemp
, a.createdBy
, a.createdDate
FROM (
SELECT e.id, e.designation, e.remark, e.moment, e.rpm, e.cycleK, e.test_id
FROM testdata_result e
ORDER BY moment asc
LIMIT 10
)e
JOIN testdata_damage AS d ON d.result_id = e.id
JOIN testdata_test AS a ON a.id = e.test_id
JOIN testdata_gear AS b ON a.id = b.test_id
JOIN testdata_damcategory as c ON c.id = d.category_id;
答案 0 :(得分:1)
INDEX(designation)
可能有所帮助。
没有LIMIT 10
,你会得到多少行?
请为每个表提供SHOW CREATE TABLE
,以便我们进一步讨论。
修改强>
没关系。 141K行的结果集(包括LONGTEXT
)需要时间。你很幸运它只需要一秒左右。那很多东西要铲倒。磁盘只能这么快;网络变得如此之快。查询或索引不是导致它“慢”的;这是请求。
141K行怎么办?当然,您不会向用户显示所有这些内容。如果你以某种方式对它们进行咀嚼,肯定需要秒,这意味着查询只是总时间的一部分。
我建议使用索引以避免执行文件排序 - 但我没有注意到它是LONGTEXT
,因此使用常规索引无效。 FULLTEXT
索引没有排序。底线:我的INDEX(designation)
无用。
基本上没有办法加快的查询。如果您需要一次获取10行,可能会有一些技术(不涉及OFFSET
)以使其更好地工作。