@@ -34,35 +34,55 @@ void isEfficient() {
3434 var explain = parse ("1|SIMPLE|t1||ALL|idx_col1_col2|idx_col1_col2|13|const|3000||Using where; Using index; Using filesort" );
3535 assertThat (analyzer .isEfficient (explain )).isFalse ();
3636
37- explain = parse ("1|SIMPLE|t1||ALL|idx_col1_col2|idx_col1_col2|13|const|100||Using where; Using index" );
38- assertThat (analyzer .isEfficient (explain )).isTrue (); // scan less than 2000 rows
39-
4037 explain = parse ("1|SIMPLE|daily_individual_stats||index_merge|PRIMARY,idx_customer_id|idx_customer_id,PRIMARY|149,149||1|100|Using intersect(idx_customer_id,PRIMARY); Using where" );
4138 assertThat (analyzer .isEfficient (explain )).isTrue ();
4239
4340 explain = parse ("1|SIMPLE|role||ALL|||||24|100|Using filesort" );
44- assertThat (analyzer .isEfficient (explain )).isTrue ();
41+ assertThat (analyzer .isEfficient (explain )).isTrue (); // scan less than 2000 rows
4542
4643 explain = parse ("1|SIMPLE|stat||range|PRIMARY,idx_customer_id|PRIMARY|3||7942|100.0|Using where; Using temporary; Using filesort" );
4744 assertThat (analyzer .isEfficient (explain )).isTrue ();
45+
46+ // not check derived table
47+ // select cust.group AS group, cust.count from (SELECT group, COUNT(*) AS count FROM customer GROUP BY group) cust
48+ // 1|PRIMARY|<derived2>||ALL|||||196830|100|
49+ // 2|DERIVED|customer||index|idx_deposit_group|idx_deposit_group|82||196830|100|Using index
50+ explain = parse ("1|PRIMARY|<derived2>||ALL|||||196830|100|" );
51+ assertThat (analyzer .isEfficient (explain )).isTrue ();
52+
53+ // order by not using index with large number of returned rows
54+ explain = parse ("1 | SIMPLE | t1 | null | ref | PRIMARY,idx_1,idx_2 | PRIMARY | 146 | const | 94212 | 100.0 | Using filesort" );
55+ assertThat (analyzer .isEfficient (explain )).isFalse ();
56+
57+ // group by not using index with large number of returned rows
58+ // SELECT type, COUNT(1) AS count FROM customer WHERE created_time < ? GROUP BY type
59+ explain = parse ("1 | SIMPLE | customer | null | ALL | idx_created_time | null | null | null | 203510 | 50.0 | Using where; Using temporary" );
60+ assertThat (analyzer .isEfficient (explain )).isFalse ();
4861 }
4962
5063 // 1|SIMPLE|daily_individual_stats||index_merge|PRIMARY,idx_customer_id|idx_customer_id,PRIMARY|149,149||1|100|Using intersect(idx_customer_id,PRIMARY); Using where
5164 MySQLQueryAnalyzer .Explain parse (String value ) {
5265 var explain = new MySQLQueryAnalyzer .Explain ();
5366 String [] parts = value .split ("\\ |" , -1 );
54- explain .id = parts [0 ];
55- explain .selectType = parts [1 ];
56- explain .table = parts [2 ];
57- explain .partitions = parts [3 ];
58- explain .type = parts [4 ];
59- explain .possibleKeys = parts [5 ];
60- explain .key = parts [6 ];
61- explain .keyLength = parts [7 ];
62- explain .ref = parts [8 ];
63- explain .rows = parts [9 ].isEmpty () ? null : Long .parseLong (parts [9 ]);
64- explain .filtered = parts [10 ];
65- explain .extra = parts [11 ];
67+ explain .id = parseString ( parts [0 ]) ;
68+ explain .selectType = parseString ( parts [1 ]) ;
69+ explain .table = parseString ( parts [2 ]) ;
70+ explain .partitions = parseString ( parts [3 ]) ;
71+ explain .type = parseString ( parts [4 ]) ;
72+ explain .possibleKeys = parseString ( parts [5 ]) ;
73+ explain .key = parseString ( parts [6 ]) ;
74+ explain .keyLength = parseString ( parts [7 ]) ;
75+ explain .ref = parseString ( parts [8 ]) ;
76+ explain .rows = parts [9 ].isEmpty () ? null : Long .parseLong (parts [9 ]. trim () );
77+ explain .filtered = parseString ( parts [10 ]) ;
78+ explain .extra = parseString ( parts [11 ]) ;
6679 return explain ;
6780 }
81+
82+ String parseString (String value ) {
83+ if (value .isEmpty ()) return null ;
84+ String trim = value .trim ();
85+ if (trim .equalsIgnoreCase ("null" )) return null ;
86+ return trim ;
87+ }
6888}
0 commit comments