0

我正在尝试将我们服务器上的响应时间降低到 250 毫秒范围内,大多数查询需要不到一毫秒的时间,而这一次需要很长时间。由于行数很大,超过 1500 毫秒。这是数据结构,是否可以采取任何措施来减少此查询的时间,或者使用不同的查询或以某种方式更快地设置我的数据?

mysql> describe variant_bikes;

+------------+-----------------------+------+-----+---------+-------+
| Field      | Type                  | Null | Key | Default | Extra |
+------------+-----------------------+------+-----+---------+-------+
| variant_id | mediumint(8) unsigned | NO   | PRI | 0       |       |
| bike_id    | mediumint(8) unsigned | NO   | PRI | 0       |       |
+------------+-----------------------+------+-----+---------+-------+

mysql> describe cscart_product_option_variants;

+----------------------+-----------------------+------+-----+---------+----------------+
| Field                | Type                  | Null | Key | Default | Extra          |
+----------------------+-----------------------+------+-----+---------+----------------+
| variant_id           | mediumint(8) unsigned | NO   | PRI | NULL    | auto_increment |
+----------------------+-----------------------+------+-----+---------+----------------+
15 rows in set (0.00 sec)

mysql> describe bikefilter_cache;
+---------+-----------------------+------+-----+---------+----------------+
| Field   | Type                  | Null | Key | Default | Extra          |
+---------+-----------------------+------+-----+---------+----------------+
| bike_id | mediumint(8) unsigned | NO   | PRI | NULL    | auto_increment |
| year    | smallint(6) unsigned  | NO   | PRI | NULL    |                |
| make    | varchar(20)           | NO   | PRI | NULL    |                |
| line    | varchar(20)           | NO   | PRI | NULL    |                |
| model   | varchar(90)           | NO   | PRI | NULL    |                |
+---------+-----------------------+------+-----+---------+----------------+

mysql> select count(*) from variant_bikes;

+----------+
| count(*) |
+----------+
|  7577597 |
+----------+
1 row in set (1.85 sec)

mysql> select variant_id from variant_bikes where bike_id=112;
9366 rows in set (2.30 sec)

我之前尝试过的一件事,我认为至少在当时的大小上要慢得多,就是让 variant_bikes 成为一个带有 variant_id 的表,但 bike_ids 字段是 varchar 和/或文本,并且您搜索了一个逗号分隔的列表。

我想到的另一件事可能是将所有表排列成不同的更有效的数据结构。

4

2 回答 2

3

为了获得该查询的最佳性能,请添加一个 index ON variant_bikes (bike_id, variant_id)

这将是查询的“覆盖”索引,MySQL 将能够仅“使用索引”块来满足查询,而无需从表中引用(查找)任何数据块。

问:为什么在已经有索引的情况下还需要这个索引(variant_id, bike_id)

A:这与索引中列的顺序有关。查询中的谓词(WHERE 子句)位于bike_id列上。为了让 MySQL 使用索引,该列需要作为索引中的前导列出现。

问:如果我只在(bike_id)列上有索引怎么办。

A: MySQL 很可能使用那个索引。查询还需要从列中返回值variant_id……为了获得最佳性能,我们只想满足来自索引块的查询。根据 MySQL 的版本和存储引擎,MySQL 可能能够variant_id从索引返回 just (bike_id),因为主键列的值是返回数据块的“指针”。

您可以尝试添加该索引,然后运行一个EXPLAIN SELECT ...,您希望看到的最后一列(额外)是“使用索引”,这表明查询已从索引中得到满足,而无需引用表中的块。

... key             Extra        
--- -------------   -------------
    bike_id_index   Using index
于 2012-08-31T16:46:01.013 回答
0

您的variant_bikes主键是一个复合键(variant_id, bike_id),您正在搜索该复合键的后半部分。所以你不能使用索引。

添加一个索引bike_id,一切都应该很好。

于 2012-08-31T16:20:08.460 回答