Ubuntu环境下MariaDB查询优化的核心技巧
编辑MariaDB配置文件(/etc/mysql/mariadb.conf.d/50-server.cnf 或 /etc/my.cnf),优化关键参数:
innodb_buffer_pool_size:设置为服务器总内存的50%-80%(如4G内存可设为3G-3.2G),用于缓存InnoDB表数据和索引,是提升查询性能的核心参数。innodb_log_file_size:增大日志文件尺寸(如256M-512M),减少日志刷盘次数,提高写入性能。innodb_flush_log_at_trx_commit:设为2(默认1),牺牲少量数据安全性(如系统崩溃可能丢失1秒内事务)以换取更高性能(适合对数据一致性要求不高的场景)。query_cache_size:若存在大量重复查询,可启用查询缓存(如64M-128M),缓存查询结果以减少重复计算;但需注意,频繁更新的表可能导致缓存失效频繁,反而影响性能。max_connections:根据应用并发需求调整(如500-1000),避免过多连接导致资源耗尽;同时配合thread_cache_size(如16-32)缓存线程,减少线程创建/销毁开销。tmp_table_size 和 max_heap_table_size:增大临时表大小(如256M-512M),避免大查询因临时表溢出到磁盘而变慢。CREATE INDEX idx_user_id ON users(user_id)),加速数据定位。(age, name),查询条件包含age或age AND name时可命中索引,但单独name则不能);将过滤性高的字段放在前面(如WHERE age=20 AND name='Tom',age的过滤性高于name,应放在前面)。varchar(255)),可使用前缀索引(如CREATE INDEX idx_name_prefix ON students(name(10))),减小索引体积,提高查询效率。OPTIMIZE TABLE或ALTER TABLE table_name REBUILD INDEX,保持索引高效性。EXPLAIN分析查询:执行EXPLAIN SELECT ...查看查询执行计划,重点关注:
type列为ref/range/eq_ref优于ALL(全表扫描));rows列,数值越小越好);Extra列出现Using temporary)或文件排序(Using filesort),这些会显著降低性能。SELECT *:只选择需要的列(如SELECT name, age FROM users),减少数据传输量和内存消耗。WHERE子句:
WHERE YEAR(create_time)=2025会导致索引失效,可改为WHERE create_time BETWEEN '2025-01-01' AND '2025-12-31');NOT、OR(如WHERE age!=20或WHERE age=10 OR classid=100,若classid无索引会导致全表扫描);IN代替OR(如WHERE id IN (1,2,3)比WHERE id=1 OR id=2 OR id=3更高效)。JOIN操作:
INNER JOIN(内连接),查询优化器会自动选择小表作为驱动表(数据量小的表先扫描);LEFT JOIN book ON type.card = book.card,book.card必须有索引,否则会全表扫描);type表有100条记录,book表有10万条记录,用type驱动book更高效)。LIMIT offset, size的大偏移量(如LIMIT 1000000, 10),可通过覆盖索引或主键定位优化:
SELECT t.* FROM student t, (SELECT id FROM student ORDER BY id LIMIT 1000000, 10) a WHERE t.id = a.id);WHERE id > last_id LIMIT size(如SELECT * FROM student WHERE id > 1000000 LIMIT 10,last_id为上一页最后一条记录的主键)。JOIN代替子查询(如SELECT * FROM users WHERE id IN (SELECT user_id FROM orders WHERE amount > 100)可改为SELECT users.* FROM users JOIN orders ON users.id = orders.user_id WHERE orders.amount > 100),JOIN通常更高效。SELECT age, name FROM student WHERE age > 20,创建组合索引(age, name)即可覆盖,无需回表查询原表),减少I/O操作。slow_query_log=1,long_query_time=1,记录执行时间超过1秒的查询),定期分析并优化慢查询。ANALYZE TABLE table_name更新表的统计信息,帮助查询优化器做出更准确的执行计划。OPTIMIZE TABLE table_name整理表碎片(尤其针对频繁更新的表),减少数据碎片对查询性能的影响。iostat监控磁盘I/O、vmstat监控内存/CPU、Prometheus+Grafana监控数据库指标),及时发现瓶颈(如磁盘I/O过高、内存不足)。