зеркало из https://github.com/github/vitess-gh.git
skip pk row cache optimization if there's an order by clause
display query plans for query_cache stats rowcache: limit size to 4k
This commit is contained in:
Родитель
be11a853c0
Коммит
db2be9f119
|
@ -265,26 +265,28 @@ func (self *Node) execAnalyzeSelect(getTable TableGetter) (plan *ExecPlan) {
|
|||
return plan
|
||||
}
|
||||
|
||||
if pkValues := getPKValues(conditions, tableInfo.Indexes[0]); pkValues != nil {
|
||||
plan.PlanId = PLAN_SELECT_PK
|
||||
plan.OuterQuery = self.GenerateSelectOuterQuery(tableInfo)
|
||||
plan.PKValues = pkValues
|
||||
// order
|
||||
orders := self.At(SELECT_ORDER_OFFSET).execAnalyzeOrder()
|
||||
if orders == nil {
|
||||
plan.Reason = REASON_ORDER
|
||||
return plan
|
||||
}
|
||||
|
||||
if len(orders) == 0 { // Only do pk analysis if there's no order by clause
|
||||
if pkValues := getPKValues(conditions, tableInfo.Indexes[0]); pkValues != nil {
|
||||
plan.PlanId = PLAN_SELECT_PK
|
||||
plan.OuterQuery = self.GenerateSelectOuterQuery(tableInfo)
|
||||
plan.PKValues = pkValues
|
||||
return plan
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Analyze hints to improve plan.
|
||||
if hasHints {
|
||||
plan.Reason = REASON_HAS_HINTS
|
||||
return plan
|
||||
}
|
||||
|
||||
// order
|
||||
orders := self.At(SELECT_ORDER_OFFSET).execAnalyzeOrder()
|
||||
if orders == nil {
|
||||
plan.Reason = REASON_ORDER
|
||||
return plan
|
||||
}
|
||||
|
||||
plan.IndexUsed = getIndexMatch(conditions, orders, tableInfo.Indexes)
|
||||
if plan.IndexUsed == "" {
|
||||
plan.Reason = REASON_NOINDEX_MATCH
|
||||
|
|
|
@ -829,6 +829,29 @@ select * from a where eid between 1 and 2 and name='foo'
|
|||
"SetValue": null
|
||||
}
|
||||
|
||||
# order by (pk)
|
||||
select * from a where eid=1 and id=1 order by name
|
||||
{
|
||||
"PlanId": "SELECT_CACHE_RESULT",
|
||||
"Reason": "PKINDEX",
|
||||
"TableName": "a",
|
||||
"FullQuery": "select * from a where eid = 1 and id = 1 order by name asc limit :_vtMaxResultSize",
|
||||
"OuterQuery": "select eid, id, name, foo from a where eid = 1 and id = 1 order by name asc limit :_vtMaxResultSize",
|
||||
"Subquery": null,
|
||||
"IndexUsed": "PRIMARY",
|
||||
"ColumnNumbers": [
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3
|
||||
],
|
||||
"PKValues": null,
|
||||
"SecondaryPKValues": null,
|
||||
"SubqueryPKColumns": null,
|
||||
"SetKey": "",
|
||||
"SetValue": null
|
||||
}
|
||||
|
||||
# order by
|
||||
select * from a where eid=1 order by name
|
||||
{
|
||||
|
|
|
@ -75,6 +75,11 @@ func (self *RowCache) Get(key string) (row []interface{}) {
|
|||
}
|
||||
|
||||
func (self *RowCache) Set(key string, row []interface{}, readTime time.Time) {
|
||||
// This value is hardcoded for now.
|
||||
// We're assuming it's not worth caching rows that are too large.
|
||||
if rowLen(row) > 4000 {
|
||||
return
|
||||
}
|
||||
conn := self.cachePool.Get()
|
||||
defer conn.Recycle()
|
||||
mkey := self.prefix + key
|
||||
|
@ -117,3 +122,19 @@ func (self *RowCache) Delete(key string) {
|
|||
panic(NewTabletError(FATAL, "%s", err))
|
||||
}
|
||||
}
|
||||
|
||||
func rowLen(row []interface{}) int {
|
||||
length := 0
|
||||
for _, v := range row {
|
||||
if v == nil {
|
||||
continue
|
||||
}
|
||||
switch col := v.(type) {
|
||||
case string:
|
||||
length += len(col)
|
||||
case []byte:
|
||||
length += len(col)
|
||||
}
|
||||
}
|
||||
return length
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ import (
|
|||
"code.google.com/p/vitess/go/relog"
|
||||
"code.google.com/p/vitess/go/vt/schema"
|
||||
"code.google.com/p/vitess/go/vt/sqlparser"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"sync"
|
||||
|
@ -202,8 +203,16 @@ func (self *SchemaInfo) ServeHTTP(response http.ResponseWriter, request *http.Re
|
|||
response.Write([]byte(fmt.Sprintf("Length: %d\n", len(keys))))
|
||||
for _, v := range keys {
|
||||
response.Write([]byte(fmt.Sprintf("%s\n", v)))
|
||||
if plan := self.getQuery(v); plan != nil {
|
||||
if b, err := json.MarshalIndent(plan, "", " "); err != nil {
|
||||
response.Write([]byte(err.Error()))
|
||||
} else {
|
||||
response.Write(b)
|
||||
response.Write(([]byte)("\n\n"))
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { // tables
|
||||
} else if request.URL.Path == "/debug/schema/tables" {
|
||||
response.Header().Set("Content-Type", "text/plain")
|
||||
self.mu.Lock()
|
||||
tstats := make(map[string]struct{ hits, absent, misses int64 })
|
||||
|
@ -224,5 +233,7 @@ func (self *SchemaInfo) ServeHTTP(response http.ResponseWriter, request *http.Re
|
|||
}
|
||||
fmt.Fprintf(response, "\"Totals\": {\"Hits\": %v, \"Absent\": %v, \"Misses\": %v}\n", totals.hits, totals.absent, totals.misses)
|
||||
response.Write([]byte("}\n"))
|
||||
} else {
|
||||
response.WriteHeader(http.StatusNotFound)
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче