From 026aa4e0c0e173e6722a8843cac0e78c70c34acc Mon Sep 17 00:00:00 2001 From: winkyao Date: Thu, 18 Jan 2018 22:17:39 +0800 Subject: [PATCH 1/3] server: optimize com_field_list, make use database faster. (#5677) --- server/driver_tidb.go | 16 ++++----- server/tidb_test.go | 75 +++++++++++++++++++++++++++++++++++++++++++ session.go | 28 ++++++++++++++++ 3 files changed, 109 insertions(+), 10 deletions(-) diff --git a/server/driver_tidb.go b/server/driver_tidb.go index 930785abeb39a..a0078e4f3041d 100644 --- a/server/driver_tidb.go +++ b/server/driver_tidb.go @@ -22,7 +22,6 @@ import ( "github.com/pingcap/tidb/ast" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/mysql" - "github.com/pingcap/tidb/terror" "github.com/pingcap/tidb/util" "github.com/pingcap/tidb/util/auth" "github.com/pingcap/tidb/util/types" @@ -230,19 +229,16 @@ func (tc *TiDBContext) Auth(user *auth.UserIdentity, auth []byte, salt []byte) b } // FieldList implements QueryCtx FieldList method. -func (tc *TiDBContext) FieldList(table string) (colums []*ColumnInfo, err error) { - rs, err := tc.Execute("SELECT * FROM `" + table + "` LIMIT 0") - if len(rs) > 0 { - defer terror.Call(rs[0].Close) - } +func (tc *TiDBContext) FieldList(table string) (columns []*ColumnInfo, err error) { + fields, err := tc.session.FieldList(table) if err != nil { return nil, errors.Trace(err) } - colums, err = rs[0].Columns() - if err != nil { - return nil, errors.Trace(err) + columns = make([]*ColumnInfo, 0, len(fields)) + for _, f := range fields { + columns = append(columns, convertColumnInfo(f)) } - return + return columns, nil } // GetStatement implements QueryCtx GetStatement method. diff --git a/server/tidb_test.go b/server/tidb_test.go index 69f4a60d31926..463fb96ac0f9e 100644 --- a/server/tidb_test.go +++ b/server/tidb_test.go @@ -401,3 +401,78 @@ func (ts *TidbTestSuite) TestShowCreateTableFlen(c *C) { c.Assert(int(cols[0].ColumnLength), Equals, 5*tmysql.MaxBytesOfCharacter) c.Assert(int(cols[1].ColumnLength), Equals, len(row[1].GetString())*tmysql.MaxBytesOfCharacter) } + +func checkColNames(c *C, columns []*ColumnInfo, names ...string) { + for i, name := range names { + c.Assert(columns[i].Name, Equals, name) + c.Assert(columns[i].OrgName, Equals, name) + } +} + +func (ts *TidbTestSuite) TestFieldList(c *C) { + ctx, err := ts.tidbdrv.OpenCtx(uint64(0), 0, uint8(tmysql.DefaultCollationID), "test", nil) + c.Assert(err, IsNil) + _, err = ctx.Execute(goctx.Background(), "use test;") + c.Assert(err, IsNil) + + goCtx := goctx.Background() + testSQL := `create table t ( + c_bit bit(10), + c_int_d int, + c_bigint_d bigint, + c_float_d float, + c_double_d double, + c_decimal decimal(6, 3), + c_datetime datetime(2), + c_time time(3), + c_date date, + c_timestamp timestamp(4) DEFAULT CURRENT_TIMESTAMP(4), + c_char char(20), + c_varchar varchar(20), + c_text_d text, + c_binary binary(20), + c_blob_d blob, + c_set set('a', 'b', 'c'), + c_enum enum('a', 'b', 'c'), + c_json JSON, + c_year year + )` + _, err = ctx.Execute(goCtx, testSQL) + c.Assert(err, IsNil) + colInfos, err := ctx.FieldList("t") + c.Assert(err, IsNil) + c.Assert(len(colInfos), Equals, 19) + + checkColNames(c, colInfos, "c_bit", "c_int_d", "c_bigint_d", "c_float_d", + "c_double_d", "c_decimal", "c_datetime", "c_time", "c_date", "c_timestamp", + "c_char", "c_varchar", "c_text_d", "c_binary", "c_blob_d", "c_set", "c_enum", + "c_json", "c_year") + + for _, cols := range colInfos { + c.Assert(cols.Schema, Equals, "test") + } + + for _, cols := range colInfos { + c.Assert(cols.Table, Equals, "t") + } + + for i, col := range colInfos { + switch i { + case 10, 11, 12, 15, 16: + // c_char char(20), c_varchar varchar(20), c_text_d text, + // c_set set('a', 'b', 'c'), c_enum enum('a', 'b', 'c') + c.Assert(col.Charset, Equals, uint16(tmysql.CharsetIDs["utf8"]), Commentf("index %d", i)) + continue + } + + c.Assert(col.Charset, Equals, uint16(tmysql.CharsetIDs["binary"]), Commentf("index %d", i)) + } + + // c_decimal decimal(6, 3) + c.Assert(colInfos[5].Decimal, Equals, uint8(3)) +} + +func (ts *TidbTestSuite) TestSumAvg(c *C) { + c.Parallel() + runTestSumAvg(c) +} diff --git a/session.go b/session.go index 4c8e9c65905d2..658341a836bac 100644 --- a/session.go +++ b/session.go @@ -36,6 +36,7 @@ import ( "github.com/pingcap/tidb/executor" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/meta" + "github.com/pingcap/tidb/model" "github.com/pingcap/tidb/mysql" "github.com/pingcap/tidb/parser" "github.com/pingcap/tidb/plan/cache" @@ -84,6 +85,8 @@ type Session interface { ShowProcess() util.ProcessInfo // PrePareTxnCtx is exported for test. PrepareTxnCtx() + // FieldList returns fields list of a table. + FieldList(tableName string) (fields []*ast.ResultField, err error) } var ( @@ -219,6 +222,31 @@ func (s *session) GetSessionManager() util.SessionManager { return s.sessionManager } +// FieldList returns fields list of a table. +func (s *session) FieldList(tableName string) ([]*ast.ResultField, error) { + is := executor.GetInfoSchema(s) + dbName := model.NewCIStr(s.GetSessionVars().CurrentDB) + tName := model.NewCIStr(tableName) + table, err := is.TableByName(dbName, tName) + if err != nil { + return nil, errors.Trace(err) + } + + cols := table.Cols() + fields := make([]*ast.ResultField, 0, len(cols)) + for _, col := range table.Cols() { + rf := &ast.ResultField{ + ColumnAsName: col.Name, + TableAsName: tName, + DBName: dbName, + Table: table.Meta(), + Column: col.ColumnInfo, + } + fields = append(fields, rf) + } + return fields, nil +} + type schemaLeaseChecker struct { domain.SchemaValidator schemaVer int64 From f9bdd69f952f9dc510af0131da2d4c40a90c4888 Mon Sep 17 00:00:00 2001 From: winkyao Date: Fri, 19 Jan 2018 00:52:01 +0800 Subject: [PATCH 2/3] *: cleanup --- server/tidb_test.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/server/tidb_test.go b/server/tidb_test.go index 463fb96ac0f9e..8e76c5921ba4b 100644 --- a/server/tidb_test.go +++ b/server/tidb_test.go @@ -471,8 +471,3 @@ func (ts *TidbTestSuite) TestFieldList(c *C) { // c_decimal decimal(6, 3) c.Assert(colInfos[5].Decimal, Equals, uint8(3)) } - -func (ts *TidbTestSuite) TestSumAvg(c *C) { - c.Parallel() - runTestSumAvg(c) -} From ea44b0f0af8a9bb4beb10157cc098db86042b1a3 Mon Sep 17 00:00:00 2001 From: winkyao Date: Fri, 19 Jan 2018 00:54:21 +0800 Subject: [PATCH 3/3] *: fix ci --- server/tidb_test.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/server/tidb_test.go b/server/tidb_test.go index 8e76c5921ba4b..ac60156b9a8cf 100644 --- a/server/tidb_test.go +++ b/server/tidb_test.go @@ -412,10 +412,9 @@ func checkColNames(c *C, columns []*ColumnInfo, names ...string) { func (ts *TidbTestSuite) TestFieldList(c *C) { ctx, err := ts.tidbdrv.OpenCtx(uint64(0), 0, uint8(tmysql.DefaultCollationID), "test", nil) c.Assert(err, IsNil) - _, err = ctx.Execute(goctx.Background(), "use test;") + _, err = ctx.Execute("use test;") c.Assert(err, IsNil) - goCtx := goctx.Background() testSQL := `create table t ( c_bit bit(10), c_int_d int, @@ -437,7 +436,7 @@ func (ts *TidbTestSuite) TestFieldList(c *C) { c_json JSON, c_year year )` - _, err = ctx.Execute(goCtx, testSQL) + _, err = ctx.Execute(testSQL) c.Assert(err, IsNil) colInfos, err := ctx.FieldList("t") c.Assert(err, IsNil)