Leg*_*end 6 mysql sql database query-optimization
我的桌子上有三列.
+-----------+-----------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-----------------------+------+-----+---------+-------+
| hash | mediumint(8) unsigned | NO | PRI | 0 | |
| nums | int(10) unsigned | NO | PRI | 0 | |
| acc | smallint(5) unsigned | NO | PRI | 0 | |
+-----------+-----------------------+------+-----+---------+-------+
Run Code Online (Sandbox Code Playgroud)
我期待我的数据重复,所以我继续并添加了一个独特的约束:
ALTER TABLE nt_accs ADD UNIQUE(hash,nums,acc);
Run Code Online (Sandbox Code Playgroud)
我有大约5亿行要插入到这个表中,并且这个表已经使用nums上的RANGE分成大约20个分区.
GROUP BY
使用hash和nums列的类型查询.我是否继续添加转换索引,或者我只是添加单个索引?编辑:
分区并插入一些测试数据后解释计划
1. mysql> explain partitions select * from nt_accs;
+----+-------------+-----------+---------------------------------------------------------------------------+-------+---------------+----------+---------+------+------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+---------------------------------------------------------------------------+-------+---------------+----------+---------+------+------+-------------+
| 1 | SIMPLE | nt_accs | p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20 | index | NULL | hash | 7 | NULL | 10 | Using index |
+----+-------------+-----------+---------------------------------------------------------------------------+-------+---------------+----------+---------+------+------+-------------+
1 row in set (0.00 sec)
2. mysql> explain partitions select * from nt_accs WHERE nums=1504887570;
+----+-------------+-----------+------------+-------+---------------+----------+---------+------+------+--------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+------------+-------+---------------+----------+---------+------+------+--------------------------+
| 1 | SIMPLE | nt_accs | p7 | index | NULL | hash | 7 | NULL | 10 | Using where; Using index |
+----+-------------+-----------+------------+-------+---------------+----------+---------+------+------+--------------------------+
1 row in set (0.00 sec)
3. mysql> explain partitions select * from nt_accs WHERE hash=2347200;
+----+-------------+-----------+---------------------------------------------------------------------------+------+---------------+----------+---------+-------+------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+---------------------------------------------------------------------------+------+---------------+----------+---------+-------+------+-------------+
| 1 | SIMPLE | nt_accs | p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20 | ref | hash | hash | 3 | const | 27 | Using index |
+----+-------------+-----------+---------------------------------------------------------------------------+------+---------------+----------+---------+-------+------+-------------+
1 row in set (0.00 sec)
4. mysql> EXPLAIN PARTITIONS SELECT hash, count(distinct nums) FROM nt_accs GROUP BY hash;
+----+-------------+-----------+---------------------------------------------------------------------------+-------+---------------+----------+---------+------+------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+---------------------------------------------------------------------------+-------+---------------+----------+---------+------+------+-------------+
| 1 | SIMPLE | nt_accs | p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20 | index | NULL | hash | 7 | NULL | 10 | Using index |
+----+-------------+-----------+---------------------------------------------------------------------------+-------+---------------+----------+---------+------+------+-------------+
1 row in set (0.00 sec)
5. mysql> EXPLAIN PARTITIONS SELECT nums, count(distinct hash) FROM nt_accs GROUP BY nums;
+----+-------------+-----------+---------------------------------------------------------------------------+-------+---------------+----------+---------+------+------+-----------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+---------------------------------------------------------------------------+-------+---------------+----------+---------+------+------+-----------------------------+
| 1 | SIMPLE | nt_accs | p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20 | index | NULL | hash | 7 | NULL | 10 | Using index; Using filesort |
+----+-------------+-----------+---------------------------------------------------------------------------+-------+---------------+----------+---------+------+------+-----------------------------+
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
第一次和第二次查询我完全没问题,但我不确定第3,第4和第5次的表现.在这一点上我还能做些什么来优化这个吗?
唯一约束是否会减慢插入?仅仅制作一个主键而不是强加一个独特的约束,这有何不同?
是的,索引(MySQL实现一个唯一约束作为索引)将减慢插入速度.
同样是主键,这就是为什么表期望高插入负载(IE:用于日志记录)没有定义主键的原因 - 使插入更快.
我使用hash和nums列有很多GROUP BY类型查询.我是否继续添加转换索引,或者我只是添加单个索引?
绝对知道的唯一方法是测试和检查EXPLAIN计划.
根据提供的解释计划,我没有看到对第3和第4版本的关注.MySQL每个select_type只能使用一个索引.第五个版本可能受益于覆盖指数.
只是想确保你知道:
ALTER TABLE nt_accs ADD UNIQUE(hash, nums, acc);
Run Code Online (Sandbox Code Playgroud)
...表示三列值的组合将是唯一的.IE:这些是有效的,唯一约束将允许:
hash nums acc
----------------
1 1 1
1 1 2
1 2 1
2 1 1
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2947 次 |
最近记录: |