面试题答案
一键面试1. 应用场景分析
假设我们有一个电商数据库,其中有一个products
表,记录了商品的各种信息,如product_id
、product_name
、price
、category_id
等。现在我们需要经常进行复杂查询,比如查询某个类别下价格在一定范围内的商品列表,并且按照销量排序。
2. 优化调用方式
- 减少不必要的索引扫描:
- SQLite的B - tree API在处理索引时,如果使用不当,可能会导致全索引扫描。例如,假设我们有一个复合索引
CREATE INDEX idx_product_price_cat ON products (category_id, price);
。在查询时,如果查询条件顺序与索引列顺序不一致,可能无法有效利用索引。 - 正确的查询示例(Python + SQLite3):
- SQLite的B - tree API在处理索引时,如果使用不当,可能会导致全索引扫描。例如,假设我们有一个复合索引
import sqlite3
conn = sqlite3.connect('ecommerce.db')
cursor = conn.cursor()
# 正确利用索引的查询
cursor.execute('SELECT product_id, product_name FROM products WHERE category_id =? AND price BETWEEN? AND? ORDER BY sales DESC', (1, 10, 100))
results = cursor.fetchall()
for row in results:
print(row)
conn.close()
- 这里按照索引列
category_id
和price
的顺序给出查询条件,能有效利用索引,减少B - tree的遍历范围。 - 合理使用事务:
- 在进行多个相关查询时,将这些查询放在一个事务中可以减少磁盘I/O操作。例如,我们要查询某个商品的详细信息以及该商品所在类别的其他商品推荐。
- 代码示例:
import sqlite3
conn = sqlite3.connect('ecommerce.db')
cursor = conn.cursor()
try:
conn.execute('BEGIN')
# 查询商品详细信息
cursor.execute('SELECT * FROM products WHERE product_id =?', (123,))
product_detail = cursor.fetchone()
print(product_detail)
# 查询同类商品推荐
cursor.execute('SELECT product_id, product_name FROM products WHERE category_id = (SELECT category_id FROM products WHERE product_id =?) AND product_id!=? LIMIT 5', (123, 123))
related_products = cursor.fetchall()
for product in related_products:
print(product)
conn.execute('COMMIT')
except Exception as e:
print(f"Error: {e}")
conn.execute('ROLLBACK')
finally:
conn.close()
- 通过事务,SQLite在执行这些查询时可以更高效地管理B - tree数据结构,减少对B - tree的重复打开和关闭操作。
- 预编译SQL语句:
- 对于重复执行的复杂查询,预编译SQL语句可以提高性能。每次执行未预编译的SQL语句,SQLite都需要解析、编译和优化该语句,这涉及对B - tree API的额外操作。
- 示例代码:
import sqlite3
conn = sqlite3.connect('ecommerce.db')
cursor = conn.cursor()
# 预编译查询
query = 'SELECT product_id, product_name FROM products WHERE category_id =? AND price >?'
stmt = conn.cursor().prepare(query)
for category_id in [1, 2, 3]:
for min_price in [50, 100]:
stmt.bind((category_id, min_price))
results = stmt.execute().fetchall()
for row in results:
print(row)
conn.close()
- 预编译语句在第一次编译后可以缓存执行计划,后续执行时直接使用缓存的计划,减少对B - tree API不必要的解析和优化操作,从而提高查询性能。