DDL執行 線上伺服器執行DDL,更新表結構,需要謹慎,結構更改會導致全表被獨占鎖定(新版本有改善) 避免這種情況,使用COPY策略,而不是直接執行ALTER TABLE語句 思路:創建一個新表,滿足新要求,將舊表數據逐條導入新表,同時表上可以執行其他任務,導入的過程其他任務都記錄在日誌,導入完成後 ...
DDL執行
線上伺服器執行DDL,更新表結構,需要謹慎,結構更改會導致全表被獨占鎖定(新版本有改善)
避免這種情況,使用COPY策略,而不是直接執行ALTER TABLE語句
思路:創建一個新表,滿足新要求,將舊表數據逐條導入新表,同時表上可以執行其他任務,導入的過程其他任務都記錄在日誌,導入完成後根據日誌更新新表,最後新表替換舊表(Java等代碼中實現)
數據導入語句
在恢複數據時,需要大量的數據導入
思路:導入時,先禁用索引和約束;導入完畢後,再開啟索引和約束,一次性創建索引
有可能使用到的語句:禁用索引和開啟索引
ALTER TABLE [table-name] DISABLE KEYS; ALTER TABLE [table-name] ENABLE KEYS;
對於InnoDB存儲引擎,可以將多條SQL放入一個事務中完成
可以使用prepare預編譯的方案執行導入操作,減少相同結構的SQL編譯次數
大容量頁碼LIMIT
儘量不要使用大的OFFSET,比如LIMIT 10000,10
思路:儘量使用條件過濾,完成數據篩選,而不是通過OFFSET跳過已經查詢到的數據
SELECT *
不要使用SELECT *,而是使用具體的欄位;這一點對性能影響不是很大,不過這是規範
ORDER BY RAND()不要用
這句話是隨機排序,如果業務要隨機選擇儘量在伺服器代碼中實現,隨機生成主鍵進行檢索
單表和多表查詢
儘量使用單表查詢來代替多表查詢,原因有以下幾點:
(1)單表計算的壓力在java代碼,多表計算的壓力在資料庫
(2)多表查詢會一個一個表依次執行,最後再合併結果
(3)多表查詢會增加鎖定時間,降低程式併發性能
COUNT(*)
MYISAM會自動存儲COUNT(*)的值,INNODB沒有內部計數器,執行這句話相對來說較慢
解決思路:額外創建一張表,把COUNT(*)的值記錄下來
另外:
COUNT(ID)表示的是:統計ID欄位不為NULL的數量
COUNT(1)表示的是:統計記錄數量,和COUNT(*)幾乎一樣
LIMIT 1
如果你確定查到的結果只有一個,那麼加入LIMIT 1會提高性能
慢查詢日誌
用於記錄執行時間超過某個臨界值的SQL的日誌,用戶快速定位慢查詢
開啟該日誌:
查詢是否開啟
SHOW VARIABLES LIKE 'slow_query_log';
開啟
SET GLOBAL slow_query_log=On;
開啟後會在數據目錄創建slow.log文件
查看臨界時間,預設是十秒,很長
SHOW VARIABLES LIKE 'long_query_time';
設置臨界時間
SET long_query_time = 0.5;
一旦超過了0.5秒,就會被自動記錄
PROFILE信息統計
詳細記錄SQL語句執行時間的工具
開啟PROFILE:
SET profiling=On;
使用命令查看結果
SHOW PROFILES;
具體某條的詳情
SHOW PROFILE FOR QUERY [query_id]
典型的伺服器配置
(1)MAX_CONNECTIONS:當前MySQL允許最大連接數151個
(2)table_open_cache:表句柄緩存2000
(3)KEY_BUFFER_SIZE:索引緩衝大小8388608
(4)innodb_buffer_pool_size:INNODB存儲引擎緩存池大小,比較重要,儘可能地設置更大
(5)innodb_file_per_table:INNODB表的獨立表文件,ON就表示一個表對應一個表文件,否則所有INNODB表文件存到一起
以上的配置全部取決於實際的運行環境
mysqlslap壓力測試工具
這是一個mysql自帶的工具,是一個EXE,直接運行即可,具體的百度,這是DBA的工作,不是程式員的工作