MST

星途 面试题库

面试题:MySQL读多写少场景下,如何合理使用表级锁来优化性能?

在MySQL读多写少的应用场景中,表级锁是常用的锁机制之一。请阐述在这种场景下,怎样设置和使用表级锁,能够在保证数据一致性的前提下,最大程度地提高系统的并发读性能,并举例说明相关的SQL语句。
29.9万 热度难度
数据库MySQL

知识考点

AI 面试

面试题答案

一键面试
  1. 设置与使用
    • 共享锁(读锁)
      • 在MySQL中,可以使用 LOCK TABLES table_name READ 语句对表加共享锁。共享锁允许多个会话同时读取表数据,这样在读取数据时不会相互阻塞,提高了并发读性能。例如:
LOCK TABLES products READ;
SELECT * FROM products;
UNLOCK TABLES;
  - 当一个会话对表加了共享锁后,其他会话可以继续对该表加共享锁来读取数据,但不能加排他锁(写锁)进行写入操作,直到所有共享锁被释放。
  • 优化查询
    • 确保查询语句尽量使用索引,以减少锁的持有时间。例如,如果查询语句是 SELECT * FROM products WHERE product_id = 123;,那么在 product_id 列上创建索引可以提高查询效率,进而提高并发读性能。创建索引的语句为:
CREATE INDEX idx_product_id ON products(product_id);
  • 合理安排事务
    • 尽量缩短事务的执行时间,减少锁的持有时间。例如,如果一个事务只是简单的读取操作,可以将其设计为自动提交模式,而不是手动开启和提交事务。在MySQL中,默认是自动提交模式,如果要手动控制事务,开启事务使用 START TRANSACTION,提交使用 COMMIT,回滚使用 ROLLBACK。对于简单读操作,建议保持自动提交模式,这样每次读取操作完成后锁就会立即释放。
  1. 数据一致性保证
    • 虽然共享锁允许多个会话同时读,但在有写操作时,会使用排他锁(写锁)。使用 LOCK TABLES table_name WRITE 对表加排他锁,加排他锁后,其他会话既不能加共享锁也不能加排他锁,直到排他锁被释放。例如:
LOCK TABLES products WRITE;
UPDATE products SET price = price * 1.1 WHERE product_id = 123;
UNLOCK TABLES;
  • 这样可以保证在写操作时,数据不会被其他会话修改,从而保证数据一致性。在读取操作时,由于共享锁的存在,也能保证读取到的数据是一致的,因为写操作会等待所有共享锁释放后才能加排他锁进行写入。