SQL查询设计思路
- 关联表:通过
customers
表的主键(如 customer_id
)与 accounts
表的 customer_id
建立关联,再通过 accounts
表的主键(如 account_id
)与 transactions
表的 account_id
建立关联。
- 时间筛选:在
transactions
表中,通过时间字段(如 transaction_date
)筛选出过去一周内的交易记录。假设当前日期可以通过数据库函数获取(如 MySQL 的 CURRENT_DATE
),则筛选条件可以是 transaction_date >= CURRENT_DATE - INTERVAL 7 DAY
。
示例 SQL(以 MySQL 为例):
SELECT t.*
FROM customers c
JOIN accounts a ON c.customer_id = a.customer_id
JOIN transactions t ON a.account_id = t.account_id
WHERE c.customer_id =? -- 传入具体客户ID
AND t.transaction_date >= CURRENT_DATE - INTERVAL 7 DAY;
索引策略
- customers表:在
customer_id
字段上创建索引,加速 customers
表与 accounts
表的连接。
CREATE INDEX idx_customers_customer_id ON customers(customer_id);
- accounts表:在
customer_id
和 account_id
字段上分别创建索引。customer_id
索引用于连接 customers
表,account_id
索引用于连接 transactions
表。
CREATE INDEX idx_accounts_customer_id ON accounts(customer_id);
CREATE INDEX idx_accounts_account_id ON accounts(account_id);
- transactions表:在
account_id
和 transaction_date
字段上创建复合索引。该复合索引能同时加速连接 accounts
表和筛选过去一周的交易记录。
CREATE INDEX idx_transactions_account_date ON transactions(account_id, transaction_date);
锁机制处理
- 行级锁:在高并发场景下,应尽量使用行级锁而非表级锁。因为行级锁只锁定需要操作的行,对其他行的并发操作影响较小。以 MySQL 为例,默认的 InnoDB 存储引擎在执行
SELECT... FOR UPDATE
语句时会对选中的行加行级锁。
SELECT t.*
FROM customers c
JOIN accounts a ON c.customer_id = a.customer_id
JOIN transactions t ON a.account_id = t.account_id
WHERE c.customer_id =?
AND t.transaction_date >= CURRENT_DATE - INTERVAL 7 DAY
FOR UPDATE;
- 减少锁持有时间:尽快完成事务,释放锁资源。在获取到所需数据后,应立即提交事务,避免长时间持有锁导致其他事务等待。
不同隔离级别对查询性能的影响
- 读未提交(Read Uncommitted):
- 优点:查询性能最高,因为不会对数据加锁,能快速获取数据。
- 缺点:可能会读到未提交的数据(脏读),无法保证数据一致性,在金融系统中不可接受。
- 读已提交(Read Committed):
- 优点:避免了脏读,能保证读到的数据都是已提交的。在这种隔离级别下,查询只会锁定当前读取的行,其他事务可以继续对未读取的行进行操作。
- 缺点:可能会出现不可重复读的情况,即同一事务内多次读取同一数据可能会得到不同结果,因为其他事务可能在两次读取之间修改并提交了数据。性能相比读未提交略低,因为需要加锁。
- 可重复读(Repeatable Read):
- 优点:在同一事务内多次读取同一数据时,能保证读取结果一致,避免了不可重复读。MySQL 的 InnoDB 存储引擎在可重复读隔离级别下,通过 MVCC(多版本并发控制)机制实现高并发下的数据一致性,对于查询操作性能影响相对较小。
- 缺点:可能会出现幻读,即同一事务内多次查询,由于其他事务插入新数据,导致查询结果集发生变化。性能略低于读已提交,因为需要维护更多的版本信息。
- 串行化(Serializable):
- 优点:完全保证数据一致性,通过对所有操作加锁,将并发操作串行化。
- 缺点:性能最低,因为所有事务都只能串行执行,会导致大量的锁等待,严重影响系统并发性能,在高并发金融系统中很少使用。