【環境介紹】
系統環境:騰訊雲 + 5.7.18+Navicat 11.2.7(客戶端)
【情況描述】
早上執行update語句報錯分析:
使用Navicat 11.2.7版本執行報錯
UPDATE shx_xxx.user_xxx SET roxx_id='xxxxxxxxxxxxxxxxxx0001' WHERE usxx_id='xxxxxxxxxxxxxxxxxx35';
報錯信息:
[Err] 1055 - Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggregated column
'information_schema.PROFILING.SEQ' which is not functionally dependent on columns in GROUP BY clause;
this is incompatible with sql_mode=only_full_group_by
【情況分析】
查看報錯信息提示only_full_group_by,該報錯一般是在查詢時候用到,單純的update語句且條件沒有group by跟order by語句,比較奇怪
查看sql_mode解釋:
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
ONLY_FULL_GROUP_BY為MySQL 5.7.4版本的新增的參數:對於GROUP BY聚合操作,如果在SELECT中的列,沒有在GROUP BY中出現,那么這個SQL是不合法的,因為列不在GROUP BY從句中;
但是使用workbench工具update正常,跟蹤通用日志(general_log),發現使用在更新的時候有查詢information_schema.PROFILING操作,該視圖為記錄SQL執行的消耗信息,該查詢不符合ONLY_FULL_GROUP_BY參數限制,所以才會出現報錯
show variables like '%gen%';
set global general_log=1;
update xxxxx set xxxx;
set global general_log=0;
show variables like '%gen%'; 》》》注意觀察一定關閉該參數,否則產生大量的日志信息
2020-01-08T15:20:47.934694+08:00 2605922 Query SHOW GLOBAL STATUS
2020-01-08T15:20:48.837771+08:00 2608143 Query SET PROFILING=1
2020-01-08T15:20:48.840037+08:00 2608143 Query SHOW STATUS
2020-01-08T15:20:48.845610+08:00 2608143 Query SHOW STATUS
2020-01-08T15:20:48.853304+08:00 2608143 Query UPDATE shx_xxx.user_xxx SET roxx_id='xxxxxxxxxxxxxxxxxx0001' WHERE usxx_id='xxxxxxxxxxxxxxxxxx35';
2020-01-08T15:20:48.857803+08:00 2608143 Query SHOW STATUS
2020-01-08T15:20:48.863344+08:00 2608143 Query SELECT QUERY_ID, SUM(DURATION) AS SUM_DURATION FROM INFORMATION_SCHEMA.PROFILING GROUP BY QUERY_ID
2020-01-08T15:20:48.867054+08:00 2608143 Query SELECT STATE AS `狀態`, ROUND(SUM(DURATION),7) AS `期間`, CONCAT(ROUND(SUM(DURATION)/0.000846*100,3), '%') AS `百分比`
FROM INFORMATION_SCHEMA.PROFILING WHERE QUERY_ID=39 GROUP BY STATE ORDER BY SEQ
【總結】
使用Navicat 11.2.7版本執行報錯,使用Navicat 12.1.8正常,使用workbench工具正常,建議使用新版本Navicat,workbench,SQLyog工具。
當然可以按照修改sql_mode參數進行規避,但是該only_full_group_by特性SQL寫法標准化類似Oracle的SQL語句寫法,沒有特殊要求(業務不能修改相關SQL腳本)不建議修改該參數進行規避操作;