我有一个大约有3000000行的表,如下所示。
Field |Type |Null|Key|Default|Extra |
------------------|------------|----|---|-------|--------------|
id |bigint(20) |NO |PRI| |auto_increment|
entity_name |varchar(50) |YES | | | |
field_type |varchar(50) |YES |MUL| | |
kv_key |text |YES |MUL| | |
kv_value |text |YES |MUL| | |
value_type |int(11) |YES | | | |
dataset_id |varchar(255)|YES |MUL| | |
dataset_version_id|varchar(255)|YES |MUL| | |
experiment_id |varchar(255)|YES |MUL| | |
experiment_run_id |varchar(255)|YES |MUL| | |
job_id |varchar(255)|YES |MUL| | |
project_id |varchar(255)|YES |MUL| | |它的索引如下
Table |Non_unique|Key_name |Seq_in_index|Column_name |Collation|Cardinality|Sub_part|Packed|Null|Index_type|Comment|Index_comment|
--------|----------|-------------|------------|------------------|---------|-----------|--------|------|----|----------|-------|-------------|
keyvalue| 0|PRIMARY | 1|id |A | 0| | | |BTREE | | |
keyvalue| 1|kv_dsv_id | 1|dataset_version_id|A | 0| | |YES |BTREE | | |
keyvalue| 1|kv_p_id | 1|project_id |A | 0| | |YES |BTREE | | |
keyvalue| 1|kv_j_id | 1|job_id |A | 0| | |YES |BTREE | | |
keyvalue| 1|kv_e_id | 1|experiment_id |A | 0| | |YES |BTREE | | |
keyvalue| 1|kv_d_id | 1|dataset_id |A | 0| | |YES |BTREE | | |
keyvalue| 1|kv_er_id | 1|experiment_run_id |A | 0| | |YES |BTREE | | |
keyvalue| 1|kv_field_type| 1|field_type |A | 0| | |YES |BTREE | | |
keyvalue| 1|kv_kv_val | 1|kv_value |A | 0| 255| |YES |BTREE | | |
keyvalue| 1|kv_kv_key | 1|kv_key |A | 0| 255| |YES |BTREE | | |select count(*)在178ms内返回的解释
id |count |task|operator info |
------------------|----------|----|-----------------------------------------------------------------------------|
StreamAgg_48 |1.00 |root|funcs:count(col_0) |
└─IndexReader_49 |1.00 |root|index:StreamAgg_8 |
└─StreamAgg_8 |1.00 |cop |funcs:count(1) |
└─IndexScan_39|2964754.00|cop |table:keyvalue, index:dataset_version_id, range:[NULL,+inf], keep order:false|实际的查询是关于2.6 sec的。
trace format = 'row' select count(*) from keyvalue;
operation |startTS |duration |
---------------------|---------------|------------|
session.getTxnFuture |20:21:00.074939|6.455µs |
├─session.Execute |20:21:00.074937|999.484µs |
├─session.ParseSQL |20:21:00.074980|17.226µs |
├─executor.Compile |20:21:00.075010|340.281µs |
├─session.runStmt |20:21:00.075370|525.307µs |
├─session.CommitTxn|20:21:00.075882|3.542µs |
├─recordSet.Next |20:21:00.075946|2.585509798s|
├─streamAgg.Next |20:21:00.075948|2.585497556s|
├─tableReader.Next |20:21:00.075950|2.585418751s|
├─tableReader.Next |20:21:02.661433|2.77µs |
├─recordSet.Next |20:21:02.661488|11.319µs |
└─streamAgg.Next |20:21:02.661491|587ns |我的tidb设置如下
storage--tidb-discovery-f96cbd845-kgbvx 1/1 Running 0 94d
storage--tidb-operator--controller-manager-fff86dd78-b7rmh 1/1 Running 0 3d19h
storage--tidb-pd-0 1/1 Running 0 3d18h
storage--tidb-pd-1 1/1 Running 0 3d18h
storage--tidb-pd-2 1/1 Running 0 3d18h
storage--tidb-tidb-0 2/2 Running 0 3d18h
storage--tidb-tidb-1 2/2 Running 0 3d18h
storage--tidb-tidb-initializer-9fff8f78d-gh4pr 1/1 Running 0 3d22h
storage--tidb-tikv-0 1/1 Running 0 3d18h
storage--tidb-tikv-1 1/1 Running 0 3d18h
storage--tidb-tikv-2 1/1 Running 0 3d18h
storage--tidb-tikv-3 1/1 Running 0 3d18hTIDB版本
version() |
------------------|
5.7.25-TiDB-v3.0.4|如何加快查询速度?我也很好奇为什么查询会选择它选择的索引。
发布于 2020-02-18 14:04:41
我是TiDB的开发者。对于您的问题:
表中有3000000行,SQL是一个非常简单的行。执行计划已经是最好的(部分聚合推送到TiKV)。所以我建议你增加一些执行并发性,如下所示:tidb(localhost:4000)>显示变量,如"% concurrency %";+------------------------------------+-------+ | Value |Value| +------------------------------------+-------+ | Variable_name | innodb_commit_concurrency0|| innodb_concurrency_tickets | 5000 || innodb_thread_concurrency |0|| thread_concurrency | 10 || tidb_build_stats_concurrency |4|| tidb_checksum_table_concurrency |4|| tidb_distsql_scan_concurrency | 15 || tidb_hash_join_concurrency |5|| tidb_hashagg_final_concurrency4|| tidb_hashagg_partial_concurrency |4|| tidb_index_lookup_concurrency |4|| tidb_index_lookup_join_concurrency |4|| tidb_index_serial_scan_concurrency |1|| tidb_opt_concurrency_factor |3|| tidb_projection_concurrency |4|| tidb_window_concurrency |4|+
对于您的SQL,tidb_distsql_scan_concurrency可能会起作用。最好将它设置为您的(number of CPU cores / 8 * 15)。您可以使用set session/global tidb_distsql_scan_concurrency=?来更改它。
因为count(*)等同于count(1),所以索引键值对的字节数小于计划扫描的键值对的字节数。这里有一些博客供参考:TiDB Internal (I) - Data Storage
https://stackoverflow.com/questions/60268973
复制相似问题