Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
104206: sql: unskip TestTxnContentionEventsTable r=gtr a=gtr

Informs: #102660.

Release note: None

104208: indexrec: improve recommendations for queries with inequalities r=qiyanghe1998 a=qiyanghe1998

Fixes #102206

As for the tests, since !=, IS DISTINT FROM and IS NOT are categorized as range
index, so I copied similar tests with "R": R, EQ + R, J + R, EQ + J + R.

Release note: None

Epic: None

Co-authored-by: gtr <[email protected]>
Co-authored-by: qiyanghe1998 <[email protected]>
  • Loading branch information
3 people committed Jun 1, 2023
3 parents 121a345 + ec74a8f + 5f50b7a commit edcd40a
Show file tree
Hide file tree
Showing 3 changed files with 218 additions and 3 deletions.
2 changes: 0 additions & 2 deletions pkg/sql/crdb_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ import (
"github.com/cockroachdb/cockroach/pkg/storage/enginepb"
"github.com/cockroachdb/cockroach/pkg/testutils"
"github.com/cockroachdb/cockroach/pkg/testutils/serverutils"
"github.com/cockroachdb/cockroach/pkg/testutils/skip"
"github.com/cockroachdb/cockroach/pkg/testutils/sqlutils"
"github.com/cockroachdb/cockroach/pkg/testutils/testcluster"
"github.com/cockroachdb/cockroach/pkg/upgrade/upgradebase"
Expand Down Expand Up @@ -904,7 +903,6 @@ func TestIsAtLeastVersion(t *testing.T) {
func TestTxnContentionEventsTable(t *testing.T) {
defer leaktest.AfterTest(t)()
defer log.Scope(t).Close(t)
skip.WithIssue(t, 102660)

// Start the cluster. (One node is sufficient; the outliers system
// is currently in-memory only.)
Expand Down
7 changes: 6 additions & 1 deletion pkg/sql/opt/indexrec/candidate.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import (
// indexes by table. For Order By, the index column ordering and column
// directions are the same as how it is in the Order By.
// 2. Add a single-column index on any Range expression, comparison
// expression (=, <, >, <=, >=), and IS expression.
// expression (=, !=, <, >, <=, >=), IS and IS NOT expression.
// 3. Add a single-column index on any column that appears in a JOIN predicate.
// 4. If there exist multiple columns from the same table in a JOIN predicate,
// create a single index on all such columns.
Expand Down Expand Up @@ -123,8 +123,13 @@ func (ics *indexCandidateSet) categorizeIndexCandidates(expr opt.Expr) {
case *memo.EqExpr:
ics.addVariableExprIndex(expr.Left, ics.equalCandidates)
ics.addVariableExprIndex(expr.Right, ics.equalCandidates)
case *memo.NeExpr:
ics.addVariableExprIndex(expr.Left, ics.rangeCandidates)
ics.addVariableExprIndex(expr.Right, ics.rangeCandidates)
case *memo.IsExpr:
ics.addVariableExprIndex(expr.Left, ics.equalCandidates)
case *memo.IsNotExpr:
ics.addVariableExprIndex(expr.Left, ics.rangeCandidates)
case *memo.LtExpr:
ics.addVariableExprIndex(expr.Left, ics.rangeCandidates)
ics.addVariableExprIndex(expr.Right, ics.rangeCandidates)
Expand Down
212 changes: 212 additions & 0 deletions pkg/sql/opt/indexrec/testdata/index
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,42 @@ scan t1@_hyp_1
├── cost: 28.6200001
└── fd: ()-->(4)

index-candidates
SELECT i FROM t1 WHERE i != 5
----
t1:
(i)

index-recommendations
SELECT i FROM t1 WHERE i != 5
----
creation: CREATE INDEX ON t.public.t1 (i);
--
optimal plan:
scan t1@_hyp_1
├── columns: i:2!null
├── constraint: /2/5
│ ├── (/NULL - /4]
│ └── [/6 - ]
└── cost: 375.353333

index-candidates
SELECT s FROM t1 WHERE s IS NOT NULL
----
t1:
(s)

index-recommendations
SELECT s FROM t1 WHERE s IS NOT NULL
----
creation: CREATE INDEX ON t.public.t1 (s);
--
optimal plan:
scan t1@_hyp_1
├── columns: s:4!null
├── constraint: /4/5: (/NULL - ]
└── cost: 1067.42

index-candidates
SELECT t1.k FROM t1 JOIN t2 ON t1.k = t2.i
----
Expand Down Expand Up @@ -624,6 +660,32 @@ scan t1@_hyp_3
├── cost: 28.1933333
└── fd: ()-->(1)

index-candidates
SELECT * FROM t1 WHERE k = 1 AND f != 0
----
t1:
(f)
(k)
(k, f)

index-recommendations
SELECT * FROM t1 WHERE k = 1 AND f != 0
----
creation: CREATE INDEX ON t.public.t1 (k) STORING (i, f, s);
--
optimal plan:
select
├── columns: k:1!null i:2 f:3!null s:4
├── cost: 29.0500001
├── fd: ()-->(1)
├── scan t1@_hyp_1
│ ├── columns: k:1!null i:2 f:3 s:4
│ ├── constraint: /1/5: [/1 - /1]
│ ├── cost: 28.9200001
│ └── fd: ()-->(1)
└── filters
└── f:3 != 0.0 [outer=(3), constraints=(/3: (/NULL - /-5e-324] [/5e-324 - ]; tight)]

# Multi-column combinations used: EQ, EQ + R.
index-candidates
SELECT k, i, f FROM t1 WHERE k = 1 AND i = 2 AND f > 0
Expand Down Expand Up @@ -654,6 +716,28 @@ inner-join (zigzag t1@_hyp_1 t1@_hyp_2)
├── i:2 = 2 [outer=(2), constraints=(/2: [/2 - /2]; tight), fd=()-->(2)]
└── f:3 > 0.0 [outer=(3), constraints=(/3: [/5e-324 - ]; tight)]

index-candidates
SELECT k, i, s FROM t1 WHERE k = 1 AND i = 2 AND s IS NOT NULL
----
t1:
(i)
(k)
(k, i)
(k, i, s)
(s)

index-recommendations
SELECT k, i, s FROM t1 WHERE k = 1 AND i = 2 AND s IS NOT NULL
----
creation: CREATE INDEX ON t.public.t1 (k, i, s);
--
optimal plan:
scan t1@_hyp_5
├── columns: k:1!null i:2!null s:4!null
├── constraint: /1/2/4/5: (/1/2/NULL - /1/2]
├── cost: 18.907147
└── fd: ()-->(1,2)

# Multi-column combinations used: J + R.
index-candidates
SELECT t1.k, t1.f FROM t1 JOIN t2 ON t1.k != t2.k WHERE t1.f > 0
Expand Down Expand Up @@ -687,6 +771,39 @@ project
└── filters
└── t1.k:1 != t2.k:8 [outer=(1,8), constraints=(/1: (/NULL - ]; /8: (/NULL - ])]

index-candidates
SELECT t1.k, t1.s FROM t1 JOIN t2 ON t1.k = t2.k WHERE t1.s IS NOT NULL
----
t1:
(k)
(k, s)
(s)
t2:
(k)

index-recommendations
SELECT t1.k, t1.s FROM t1 JOIN t2 ON t1.k = t2.k WHERE t1.s IS NOT NULL
----
creation: CREATE INDEX ON t.public.t1 (s) STORING (k);
--
optimal plan:
project
├── columns: k:1!null s:4!null
├── cost: 2379.90804
└── inner-join (hash)
├── columns: t1.k:1!null t1.s:4!null t2.k:8!null
├── cost: 2282.85814
├── fd: (1)==(8), (8)==(1)
├── scan t2
│ ├── columns: t2.k:8
│ └── cost: 1078.52
├── scan t1@_hyp_1
│ ├── columns: t1.k:1 t1.s:4!null
│ ├── constraint: /4/5: (/NULL - ]
│ └── cost: 1077.32
└── filters
└── t1.k:1 = t2.k:8 [outer=(1,8), constraints=(/1: (/NULL - ]; /8: (/NULL - ]), fd=(1)==(8), (8)==(1)]

# Multi-column combinations used: EQ, EQ + J.
index-candidates
SELECT t1.i, t1.s FROM t1 JOIN t2 ON t1.k != t2.k WHERE t1.i = 2 AND t1.s = 'NG'
Expand Down Expand Up @@ -956,6 +1073,101 @@ union-all
└── aggregations
└── count-rows [as=count_rows:22]

index-candidates
SELECT count(*)
FROM t1 LEFT JOIN t2
ON t1.k = t2.k
GROUP BY t2.s, t2.i
UNION ALL
SELECT count(*)
FROM (
SELECT *
FROM t1
WHERE t1.f != 0
AND t1.s = 'NG'
)
----
t1:
(f)
(k)
(k, f)
(s)
(s, f)
(s, k)
(s, k, f)
t2:
(i, s)
(k)

index-recommendations
SELECT count(*)
FROM t1 LEFT JOIN t2
ON t1.k = t2.k
GROUP BY t2.s, t2.i
UNION ALL
SELECT count(*)
FROM (
SELECT *
FROM t1
WHERE t1.f != 0
AND t1.s = 'NG'
)
----
creation: CREATE INDEX ON t.public.t1 (k);
creation: CREATE INDEX ON t.public.t1 (s) STORING (f);
creation: CREATE INDEX ON t.public.t2 (k) STORING (i, s);
--
optimal plan:
union-all
├── columns: count:23!null
├── left columns: count_rows:14
├── right columns: count_rows:22
├── cardinality: [1 - ]
├── cost: 2766.55828
├── project
│ ├── columns: count_rows:14!null
│ ├── cost: 2727.55537
│ └── group-by (hash)
│ ├── columns: t2.i:9 t2.s:10 count_rows:14!null
│ ├── grouping columns: t2.i:9 t2.s:10
│ ├── cost: 2717.53581
│ ├── key: (9,10)
│ ├── fd: (9,10)-->(14)
│ ├── left-join (merge)
│ │ ├── columns: t1.k:1 t2.k:8 t2.i:9 t2.s:10
│ │ ├── left ordering: +1
│ │ ├── right ordering: +8
│ │ ├── cost: 2307.36
│ │ ├── scan t1@_hyp_3
│ │ │ ├── columns: t1.k:1
│ │ │ ├── cost: 1088.62
│ │ │ └── ordering: +1
│ │ ├── scan t2@_hyp_2
│ │ │ ├── columns: t2.k:8 t2.i:9 t2.s:10
│ │ │ ├── cost: 1098.72
│ │ │ └── ordering: +8
│ │ └── filters (true)
│ └── aggregations
│ └── count-rows [as=count_rows:14]
└── scalar-group-by
├── columns: count_rows:22!null
├── cardinality: [1 - 1]
├── cost: 28.9733334
├── key: ()
├── fd: ()-->(22)
├── select
│ ├── columns: f:17!null t1.s:18!null
│ ├── cost: 28.8500001
│ ├── fd: ()-->(18)
│ ├── scan t1@_hyp_1
│ │ ├── columns: f:17 t1.s:18!null
│ │ ├── constraint: /18/19: [/'NG' - /'NG']
│ │ ├── cost: 28.7200001
│ │ └── fd: ()-->(18)
│ └── filters
│ └── f:17 != 0.0 [outer=(17), constraints=(/17: (/NULL - /-5e-324] [/5e-324 - ]; tight)]
└── aggregations
└── count-rows [as=count_rows:22]

# No rule 5 multi-column index combinations.
index-candidates
Expand Down

0 comments on commit edcd40a

Please sign in to comment.