首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 數據庫優化全方位指南:從基礎操作到進階調優

     編輯:MySQL 資料庫相關知識

表結構與數據複製

快速複製表結構與數據的標準做法:

CREATE TABLE t3 LIKE t1;
INSERT INTO t3 SELECT * FROM t1;

索引管理核心語法

創建索引

-- 普通索引
ALTER TABLE table_name ADD INDEX index_name (column_list);
-- 唯一索引
ALTER TABLE table_name ADD UNIQUE (column_list);
-- 主鍵索引
ALTER TABLE table_name ADD PRIMARY KEY (column_list);

-- CREATE INDEX 方式
CREATE INDEX index_name ON table_name (column_list);
CREATE UNIQUE INDEX index_name ON table_name (column_list);

刪除索引

DROP INDEX index_name ON table_name;
ALTER TABLE table_name DROP INDEX index_name;
ALTER TABLE table_name DROP PRIMARY KEY;

視圖操作實戰

-- 創建視圖
CREATE VIEW v_t1 AS SELECT * FROM t1 WHERE id > 4 AND id < 11;

-- 查看視圖
SHOW TABLES;

-- 刪除視圖
DROP VIEW v_t1;

常用內置函數速查

字符串函數

CONCAT(str1, str2, ...)      -- 連接字符串
LCASE/UCASE(str)               -- 大小寫轉換
LENGTH(str)                    -- 字符串長度
LTRIM/RTRIM(str)               -- 去除首尾空格
REPLACE(str, search, replace)  -- 字符串替換
SUBSTRING(str, pos, len)       -- 子串提取

數學函數

CEILING/FLOOR(num)   -- 向上/向下取整
ROUND(num)           -- 四捨五入
RAND()               -- 0-1 隨機數
SQRT(num)            -- 開平方

日期時間函數

NOW()                    -- 當前日期時間
CURDATE()/CURTIME()      -- 當前日期/時間
UNIX_TIMESTAMP(date)     -- 轉 Unix 時間戳
FROM_UNIXTIME(ts)        -- 時間戳轉日期
DATEDIFF(d1, d2)         -- 日期差天數

預處理語句與事務控制

預處理語句

PREPARE stmt1 FROM 'SELECT * FROM t1 WHERE id > ?';
SET @i = 1;
EXECUTE stmt1 USING @i;
SET @i = 5;
EXECUTE stmt1 USING @i;
DEALLOCATE PREPARE stmt1;

事務與保存點

SET autocommit = 0;
DELETE FROM t1 WHERE id = 11;
SAVEPOINT p1;
DELETE FROM t1 WHERE id = 10;
SAVEPOINT p2;
ROLLBACK TO p1;  -- 回滾到 p1,p2 自動失效
ROLLBACK;        -- 完全回滾

存儲過程與觸發器

存儲過程示例

DELIMITER //
CREATE PROCEDURE p1()
BEGIN
    SET @i = 0;
    WHILE @i < 10 DO
        SELECT @i;
        SET @i = @i + 1;
    END WHILE;
END//
DELIMITER ;

CALL p1();
SHOW CREATE PROCEDURE p1\G

觸發器實戰:同步表數據

DELIMITER //
-- 插入同步
CREATE TRIGGER tg1 BEFORE INSERT ON t1
FOR EACH ROW
BEGIN
    INSERT INTO t2(id) VALUES(NEW.id);
END//

-- 刪除同步
CREATE TRIGGER tg2 BEFORE DELETE ON t1
FOR EACH ROW
BEGIN
    DELETE FROM t2 WHERE id = OLD.id;
END//

-- 更新同步
CREATE TRIGGER tg3 BEFORE UPDATE ON t1
FOR EACH ROW
BEGIN
    UPDATE t2 SET id = NEW.id WHERE id = OLD.id;
END//
DELIMITER ;

SHOW TRIGGERS;

自增 ID 重置技巧

-- 方法一:TRUNCATE(重置自增值為 1)
TRUNCATE TABLE tablename;

-- 方法二:ALTER TABLE 顯式指定
ALTER TABLE tablename AUTO_INCREMENT = 1;

GROUP BY WITH ROLLUP 進階聚合

獲取多維度小計與總計:

SELECT cname, pname, COUNT(pname)
FROM demo
GROUP BY cname, pname WITH ROLLUP;

結果包含各分組計數、各城市小計(pname 為 NULL)及總計(cname、pname 均為 NULL)。注意:WITH ROLLUP 不可與 ORDER BY 同用。

外鍵約束注意事項

CREATE TABLE temp (
    id INT,
    name CHAR(20),
    FOREIGN KEY (id) REFERENCES outTable(id)
        ON DELETE CASCADE ON UPDATE CASCADE
);

關鍵限制:僅 InnoDB 支持外鍵,MyISAM 雖可創建但不生效。

SQL 優化標準流程

1. 了解 SQL 執行頻率

SHOW [SESSION|GLOBAL] STATUS;
SHOW STATUS LIKE 'Com_%';
SHOW GLOBAL STATUS LIKE 'Com_%';

關鍵指標:Com_select、Com_insert、Slow_queries、InnoDB_rows_read 等。

2. 定位低效 SQL

EXPLAIN SELECT * FROM table WHERE id = 1000;
-- 或
DESC SELECT * FROM table WHERE id = 1000;

3. EXPLAIN 執行計劃詳解

列名含義
id查詢序號
select_type查詢類型:SIMPLE、PRIMARY、UNION、SUBQUERY 等
table輸出結果的表
type連接類型,性能由好到差:system > const > eq_ref > ref > range > index > ALL
possible_keys可能使用的索引
key實際使用的索引
key_len索引字段長度
ref與索引比較的列或常量
rows預估掃描行數
Extra額外信息:Using index、Using where、Using temporary、Using filesort 等

索引優化核心原則

索引生效場景

  • 複合索引遵循最左前綴原則,查詢條件包含最左列即可命中
  • LIKE 'prefix%'(% 不在首位)可用索引;LIKE '%suffix' 則不可
  • 大文本搜索應用全文索引而非 LIKE
  • column IS NULL 可用索引

索引失效常見原因

  1. MySQL 評估全表掃描更快(如範圍查詢覆蓋大部分數據)
  2. MEMORY/HEAP 表非「=」條件不走索引
  3. OR 條件兩側索引不完整導致全表掃描
  4. 查詢列非複合索引首列
  5. LIKE '%...' 以通配符開頭
  6. 字符串列與數值常量比較發生隱式轉換(需加引號)

索引使用狀況監控

SHOW STATUS LIKE 'Handler_read%';
  • Handler_read_key 高 → 索引命中好
  • Handler_read_rnd_next 高 → 全表掃描多,需優化

兩大實用優化命令

ANALYZE TABLE / CHECK TABLE

CHECK TABLE tbl_name [QUICK|FAST|MEDIUM|EXTENDED|CHANGED];
ANALYZE TABLE tbl_name;

OPTIMIZE TABLE

OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name;

適用於大量刪除/更新後的 MyISAM、BDB、InnoDB 表,合併空間碎片。

常用 SQL 語句優化技巧

大批量插入優化

MyISAM:禁用/啟用非唯一索引

ALTER TABLE tbl_name DISABLE KEYS;
LOAD DATA INFILE ...;
ALTER TABLE tbl_name ENABLE KEYS;

實測速度提升 10 倍以上。

InnoDB:

  • 按主鍵順序排序導入數據
  • SET unique_checks = 0 關閉唯一性檢查
  • SET autocommit = 0 關閉自動提交

INSERT 優化

  • 使用多值 INSERT INTO ... VALUES (...), (...), ...
  • 考慮 INSERT DELAYED(MyISAM)
  • 數據與索引文件分盤存放
  • 增大 bulk_insert_buffer_size(MyISAM)
  • 優先用 LOAD DATA INFILE,比多條 INSERT 快 20 倍

GROUP BY 優化

-- 禁止隱式排序
SELECT id, SUM(moneys) FROM sales2 GROUP BY id ORDER BY NULL;

去除 Using filesort,顯著降低開銷。

子查詢轉 JOIN

-- 低效子查詢
SELECT * FROM sales2 WHERE company_id NOT IN (SELECT id FROM company2);

-- 高效 LEFT JOIN
SELECT * FROM sales2
LEFT JOIN company2 ON sales2.company_id = company2.id
WHERE sales2.company_id IS NULL;

JOIN 避免臨時表創建,掃描行數大幅減少。

數據庫架構優化

表類型優化

SELECT * FROM table_name PROCEDURE ANALYSE();

獲取列類型優化建議(如建議改為 ENUM)。

大數據量解決方案

  • 分庫分表
  • 分區表
  • 中間表(視圖或物理表)

MySQL 服務器層面優化

鎖機制

  • LOCK TABLE t1 READ:共享鎖,適合備份
  • LOCK TABLE t1 WRITE:排他鎖,阻塞所有讀寫

二進制日誌與慢查詢日誌

-- 啟用 binlog
log-bin=mysql-bin

-- 查看
SHOW BINARY LOGS;
SHOW MASTER STATUS;

-- 慢查詢日誌
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2

Root 密碼重置

# 1. 停止服務
service mysqld stop

# 2. 跳過授權表啟動
mysqld_safe --skip-grant-tables --user=mysql &

# 3. 免密登錄修改密碼
mysql -uroot
UPDATE user SET password=PASSWORD('newpass') WHERE user='root' AND host='localhost';
FLUSH PRIVILEGES;

# 4. 重啟服務
service mysqld restart
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved