我有一个包含大约16万条记录的InnoDB数据库表和一个简单的更新查询,如下所示:
UPDATE table SET field='12345' WHERE order_number=102192817
需要很长时间(超过半秒)才能更新:
# Query_time: 0.609242 Lock_time: 0.000118 Rows_sent: 0 Rows_examined: 165359
我遇到的问题是,这些更新大约每2-3秒运行一次,导致服务器的整体性能下降。
服务器有8GB内存,其中4.5GB分配给mySQL,mysqltuner显示一切正常(就设置而言)。
在这种情况下,在order_number
上创建索引会有帮助吗?
发布于 2020-02-01 12:19:02
更新数据不需要那么长时间。查找要更新的记录是耗时的操作。
如果您的表在WHERE
子句中使用的列上没有索引,则MySQL需要检查表中的所有行以找到要更新的行。
通过运行,可以检查它如何找到行。
EXPLAIN SELECT * from table WHERE order_number=102192817
(使用WHERE
查询的UPDATE
子句)。
检查其输出的列key
。如果key
是NULL
,则MySQL找不到更有效地执行查询的索引。
使用CREATE INDEX
命令在列order_number
上创建索引以提高查询速度。
阅读更多关于CREATE INDEX
和命令的信息。
发布于 2020-02-01 12:16:55
您可以通过索引“order_number”字段来提高查询速度。
如果'order_number‘是唯一的,使用唯一的索引。
如果want只想更新一行,添加“限制1”。
UPDATE table SET field='12345' WHERE order_number=102192817 LIMIT 1
这个查询会更快,因为您的数据库不会查看所有记录。
发布于 2020-02-01 16:08:58
指标的重要性
由于没有索引,您的update语句必须扫描整个表。导致延迟的是where
条件。
通常,您应该考虑在以下条件下添加索引:
索引最好用于常用于where子句的列以及任何类型的排序,如"order“。 您还应该注意此信息是否会频繁更改,因为它会减慢您的更新和插入。
在您的具体情况下,order_number
似乎不像是一个将发生变化的字段。
参考: https://www.howtoforge.com/when-to-use-indexes-in-mysql-databases
如何创建索引
可以使用create命令在mysql中创建索引。有各种类型的索引,因此您可能必须决定使用哪种类型。
语法:
CREATE [UNIQUE | FULLTEXT | SPATIAL] INDEX index_name
[index_type]
ON tbl_name (key_part,...)
[index_option]
[algorithm_option | lock_option] ...
key_part: {col_name [(length)] | (expr)} [ASC | DESC]
index_option:
KEY_BLOCK_SIZE [=] value
| index_type
| WITH PARSER parser_name
| COMMENT 'string'
| {VISIBLE | INVISIBLE}
index_type:
USING {BTREE | HASH}
algorithm_option:
ALGORITHM [=] {DEFAULT | INPLACE | COPY}
lock_option:
LOCK [=] {DEFAULT | NONE | SHARED | EXCLUSIVE}
示例-添加一个简单的索引:
ALTER TABLE `your_table_name` ADD INDEX order_number_index(`order_number`)
示例-添加索引并指定类型:
create index order_number_indexon your_table_name(order_number) using HASH;
or
create index order_number_indexon your_table_name(order_number) using BTREE;
注意:支持的索引类型会根据存储引擎的不同而改变。请参阅Table 13.1 Index Types Per Storage Engine
文档中的创建索引文档。
参考资料:
https://stackoverflow.com/questions/60016577
复制相似问题