提交 c2299c3f 编写于 作者: martianzhang's avatar martianzhang

fix index col compare case sensitive bug

  CREATE TABLE test_id (
    ID int,
    PRIMARY KEY (`ID`)
  )
  SELECT * FROM test_id WHERE id=1;

  fix explain NULL able column bug

  +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------+
  | id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra                          |
  +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------+
  |  1 | SIMPLE      | NULL  | NULL       | NULL | NULL          | NULL | NULL    | NULL | NULL |     NULL | no matching row in const table |
  +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------+
上级 14c19f4d
......@@ -121,7 +121,7 @@ type Configuration struct {
ExplainWarnAccessType []string `yaml:"explain-warn-access-type"` // 哪些 access type 不建议使用
ExplainMaxKeyLength int `yaml:"explain-max-keys"` // 最大 key_len
ExplainMinPossibleKeys int `yaml:"explain-min-keys"` // 最小 possible_keys 警告
ExplainMaxRows int `yaml:"explain-max-rows"` // 最大扫描行数警告
ExplainMaxRows int64 `yaml:"explain-max-rows"` // 最大扫描行数警告
ExplainWarnExtra []string `yaml:"explain-warn-extra"` // 哪些 extra 信息会给警告
ExplainMaxFiltered float64 `yaml:"explain-max-filtered"` // filtered 大于该配置给出警告
ExplainWarnScalability []string `yaml:"explain-warn-scalability"` // 复杂度警告名单
......@@ -641,7 +641,7 @@ func readCmdFlags() error {
explainWarnAccessType := flag.String("explain-warn-access-type", strings.Join(Config.ExplainWarnAccessType, ","), "ExplainWarnAccessType, 哪些access type不建议使用")
explainMaxKeyLength := flag.Int("explain-max-keys", Config.ExplainMaxKeyLength, "ExplainMaxKeyLength, 最大key_len")
explainMinPossibleKeys := flag.Int("explain-min-keys", Config.ExplainMinPossibleKeys, "ExplainMinPossibleKeys, 最小possible_keys警告")
explainMaxRows := flag.Int("explain-max-rows", Config.ExplainMaxRows, "ExplainMaxRows, 最大扫描行数警告")
explainMaxRows := flag.Int64("explain-max-rows", Config.ExplainMaxRows, "ExplainMaxRows, 最大扫描行数警告")
explainWarnExtra := flag.String("explain-warn-extra", strings.Join(Config.ExplainWarnExtra, ","), "ExplainWarnExtra, 哪些extra信息会给警告")
explainMaxFiltered := flag.Float64("explain-max-filtered", Config.ExplainMaxFiltered, "ExplainMaxFiltered, filtered大于该配置给出警告")
explainWarnScalability := flag.String("explain-warn-scalability", strings.Join(Config.ExplainWarnScalability, ","), "ExplainWarnScalability, 复杂度警告名单, 支持O(n),O(log n),O(1),O(?)")
......
......@@ -42,13 +42,16 @@ func ExampleIsColsPart() {
b := []*Column{{Name: "1"}, {Name: "2"}}
c := []*Column{{Name: "1"}, {Name: "3"}}
d := []*Column{{Name: "1"}, {Name: "2"}, {Name: "3"}, {Name: "4"}}
id := []*Column{{Name: "id"}}
iD := []*Column{{Name: "iD"}}
ab := IsColsPart(a, b)
ac := IsColsPart(a, c)
ad := IsColsPart(a, d)
idiD := IsColsPart(id, iD) // 大小写对比
fmt.Println(ab, ac, ad)
// Output: true false true
fmt.Println(ab, ac, ad, idiD)
// Output: true false true true
Log.Debug("Exiting function: %s", GetFunctionName())
}
......
......@@ -93,7 +93,9 @@ func IsColsPart(a, b []*Column) bool {
}
for i := 0; i < times; i++ {
if a[i].DB != b[i].DB || a[i].Table != b[i].Table || a[i].Name != b[i].Name {
if strings.ToLower(a[i].DB) != strings.ToLower(b[i].DB) ||
strings.ToLower(a[i].Table) != strings.ToLower(b[i].Table) ||
strings.ToLower(a[i].Name) != strings.ToLower(b[i].Name) {
return false
}
}
......
......@@ -84,7 +84,7 @@ type ExplainRow struct {
Key string
KeyLen string // 索引长度,如果发生了index_merge, KeyLen 格式为 N,N,所以不能定义为整型
Ref []string
Rows int
Rows int64
Filtered float64 // 5.6 JSON, 5.7+, 5.5 EXTENDED
Scalability string // O(1), O(n), O(log n), O(log n)+
Extra string
......@@ -131,7 +131,7 @@ type ExplainJSONTable struct {
UsedKeyParts []string `json:"used_key_parts"`
KeyLength string `json:"key_length"`
Ref []string `json:"ref"`
RowsExaminedPerScan int `json:"rows_examined_per_scan"`
RowsExaminedPerScan int64 `json:"rows_examined_per_scan"`
RowsProducedPerJoin int `json:"rows_produced_per_join"`
Filtered string `json:"filtered"`
UsingIndex bool `json:"using_index"`
......@@ -318,6 +318,7 @@ var ExplainAccessType = map[string]string{
// ExplainScalability ACCESS TYPE对应的运算复杂度 [AccessType]scalability map
var ExplainScalability = map[string]string{
"NULL": "NULL",
"ALL": "O(n)",
"index": "O(n)",
"range": "O(log n)+",
......@@ -784,7 +785,7 @@ func parseTraditionalExplainText(content string) (explainRows []ExplainRow, err
colsMap := make(map[string]string)
for _, l := range lines[3:] {
var keylen string
var rows int
var rows int64
var filtered float64
var partitions string
// 跳过分割线
......@@ -816,7 +817,7 @@ func parseTraditionalExplainText(content string) (explainRows []ExplainRow, err
keylen = colsMap["key_len"]
rows, err = strconv.Atoi(colsMap["Rows"])
rows, err = strconv.ParseInt(colsMap["Rows"], 10, 64)
if err != nil {
rows = 0
}
......@@ -908,7 +909,7 @@ func parseVerticalExplainText(content string) (explainRows []ExplainRow, err err
}
if strings.HasPrefix(l, "Rows:") {
rows := strings.TrimPrefix(l, "Rows: ")
explainRow.Rows, err = strconv.Atoi(rows)
explainRow.Rows, err = strconv.ParseInt(rows, 10, 64)
if err != nil {
explainRow.Rows = 0
}
......@@ -957,15 +958,21 @@ func ParseExplainResult(res QueryResult, formatType int) (exp *ExplainInfo, err
}
/*
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
| 1 | SIMPLE | film | NULL | ALL | NULL | NULL | NULL | NULL | 1000 | 100.00 | NULL |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
| 1 | SIMPLE | film | NULL | ALL | NULL | NULL | NULL | NULL | 1000 | 100.00 | NULL |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | no matching row in const table |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------+
*/
// Different MySQL version has different columns define
var selectType, table, partitions, accessType, possibleKeys, key, keyLen, ref, extra []byte
var selectType, table, partitions, accessType, possibleKeys, key, keyLen, ref, extra, rows, filtered []byte
expRow := ExplainRow{}
explainFields := make([]interface{}, 0)
fields := map[string]interface{}{
......@@ -978,8 +985,8 @@ func ParseExplainResult(res QueryResult, formatType int) (exp *ExplainInfo, err
"key": &key,
"key_len": &keyLen,
"ref": &ref,
"rows": &expRow.Rows,
"filtered": &expRow.Filtered,
"rows": &rows,
"filtered": &filtered,
"Extra": &extra,
}
cols, err := res.Rows.Columns()
......@@ -1009,6 +1016,8 @@ func ParseExplainResult(res QueryResult, formatType int) (exp *ExplainInfo, err
expRow.Key = NullString(key)
expRow.KeyLen = NullString(keyLen)
expRow.Ref = strings.Split(NullString(ref), ",")
expRow.Rows = NullInt(rows)
expRow.Filtered = NullFloat(filtered)
expRow.Extra = NullString(extra)
// MySQL bug: https://bugs.mysql.com/bug.php?id=34124
......@@ -1115,7 +1124,9 @@ func PrintMarkdownExplainTable(exp *ExplainInfo) string {
}
scalability := row.Scalability
for _, s := range common.Config.ExplainWarnScalability {
scalability = "☠️ **" + s + "**"
if s == scalability {
scalability = "☠️ **" + s + "**"
}
}
buf = append(buf, fmt.Sprintln("|", row.ID, " |",
common.MarkdownEscape(row.SelectType),
......
......@@ -319,6 +319,24 @@ func NullString(buf []byte) string {
return string(buf)
}
// NullFloat null able float
func NullFloat(buf []byte) float64 {
if buf == nil {
return 0
}
f, _ := strconv.ParseFloat(string(buf), 64)
return f
}
// NullInt null able int
func NullInt(buf []byte) int64 {
if buf == nil {
return 0
}
i, _ := strconv.ParseInt(string(buf), 10, 64)
return i
}
// quoteEscape sql_mode=no_backslash_escapes
func quoteEscape(source string) string {
var buf bytes.Buffer
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册