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:
Sugu Sougoumarane 2012-03-27 12:19:39 -07:00
Родитель be11a853c0
Коммит db2be9f119
4 изменённых файлов: 69 добавлений и 12 удалений

Просмотреть файл

@ -265,12 +265,21 @@ func (self *Node) execAnalyzeSelect(getTable TableGetter) (plan *ExecPlan) {
return plan
}
// 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 {
@ -278,13 +287,6 @@ func (self *Node) execAnalyzeSelect(getTable TableGetter) (plan *ExecPlan) {
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)
}
}