Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

plan, expression: support is null in hash partition pruning #17281

Merged
merged 11 commits into from
May 20, 2020

Conversation

imtbkcat
Copy link

What problem does this PR solve?

Problem Summary:

SQL like select * from t where a is null will produce a full table scan plan in hash partition. For example:

create table t (a int, b int) partition by hash(a + b) partitions 10;
explain select * from t where a is null and b = 2;

This SQL will produce following result:

MySQL [test]> explain select * from t where a is null and b = 2;
+------------------------------+----------+-----------+-----------------------+-----------------------------------+
| id                           | estRows  | task      | access object         | operator info                     |
+------------------------------+----------+-----------+-----------------------+-----------------------------------+
| Union_16                     | 0.10     | root      |                       |                                   |
| ├─TableReader_19             | 0.01     | root      |                       | data:Selection_18                 |
| │ └─Selection_18             | 0.01     | cop[tikv] |                       | eq(test.t.b, 2), isnull(test.t.a) |
| │   └─TableFullScan_17       | 10000.00 | cop[tikv] | table:t, partition:p0 | keep order:false, stats:pseudo    |
| ├─TableReader_22             | 0.01     | root      |                       | data:Selection_21                 |
| │ └─Selection_21             | 0.01     | cop[tikv] |                       | eq(test.t.b, 2), isnull(test.t.a) |
| │   └─TableFullScan_20       | 10000.00 | cop[tikv] | table:t, partition:p1 | keep order:false, stats:pseudo    |
| ├─TableReader_25             | 0.01     | root      |                       | data:Selection_24                 |
| │ └─Selection_24             | 0.01     | cop[tikv] |                       | eq(test.t.b, 2), isnull(test.t.a) |
| │   └─TableFullScan_23       | 10000.00 | cop[tikv] | table:t, partition:p2 | keep order:false, stats:pseudo    |
| ├─TableReader_28             | 0.01     | root      |                       | data:Selection_27                 |
| │ └─Selection_27             | 0.01     | cop[tikv] |                       | eq(test.t.b, 2), isnull(test.t.a) |
| │   └─TableFullScan_26       | 10000.00 | cop[tikv] | table:t, partition:p3 | keep order:false, stats:pseudo    |
| ├─TableReader_31             | 0.01     | root      |                       | data:Selection_30                 |
| │ └─Selection_30             | 0.01     | cop[tikv] |                       | eq(test.t.b, 2), isnull(test.t.a) |
| │   └─TableFullScan_29       | 10000.00 | cop[tikv] | table:t, partition:p4 | keep order:false, stats:pseudo    |
| ├─TableReader_34             | 0.01     | root      |                       | data:Selection_33                 |
| │ └─Selection_33             | 0.01     | cop[tikv] |                       | eq(test.t.b, 2), isnull(test.t.a) |
| │   └─TableFullScan_32       | 10000.00 | cop[tikv] | table:t, partition:p5 | keep order:false, stats:pseudo    |
| ├─TableReader_37             | 0.01     | root      |                       | data:Selection_36                 |
| │ └─Selection_36             | 0.01     | cop[tikv] |                       | eq(test.t.b, 2), isnull(test.t.a) |
| │   └─TableFullScan_35       | 10000.00 | cop[tikv] | table:t, partition:p6 | keep order:false, stats:pseudo    |
| ├─TableReader_40             | 0.01     | root      |                       | data:Selection_39                 |
| │ └─Selection_39             | 0.01     | cop[tikv] |                       | eq(test.t.b, 2), isnull(test.t.a) |
| │   └─TableFullScan_38       | 10000.00 | cop[tikv] | table:t, partition:p7 | keep order:false, stats:pseudo    |
| ├─TableReader_43             | 0.01     | root      |                       | data:Selection_42                 |
| │ └─Selection_42             | 0.01     | cop[tikv] |                       | eq(test.t.b, 2), isnull(test.t.a) |
| │   └─TableFullScan_41       | 10000.00 | cop[tikv] | table:t, partition:p8 | keep order:false, stats:pseudo    |
| └─TableReader_46             | 0.01     | root      |                       | data:Selection_45                 |
|   └─Selection_45             | 0.01     | cop[tikv] |                       | eq(test.t.b, 2), isnull(test.t.a) |
|     └─TableFullScan_44       | 10000.00 | cop[tikv] | table:t, partition:p9 | keep order:false, stats:pseudo    |
+------------------------------+----------+-----------+-----------------------+-----------------------------------+

What is changed and how it works?

Proposal: xxx

What's Changed:

During partition pruning, if a column is equal to NULL, all calculation relating to it will produce null result and set a NULL flag.

How it Works:

If pruning result with a NULL flag, it will be point to p0.

Related changes

  • Need to cherry-pick to the release branch

Check List

Tests

  • Unit test

Side effects

  • No

Release note

  • planner: support is null filter condition in hash partition pruning

@imtbkcat imtbkcat requested a review from a team as a code owner May 19, 2020 05:40
@ghost ghost removed their request for review May 19, 2020 05:40
@codecov
Copy link

codecov bot commented May 19, 2020

Codecov Report

Merging #17281 into master will decrease coverage by 0.0001%.
The diff coverage is 83.8709%.

@@               Coverage Diff                @@
##             master     #17281        +/-   ##
================================================
- Coverage   79.7957%   79.7956%   -0.0002%     
================================================
  Files           520        517         -3     
  Lines        139624     139534        -90     
================================================
- Hits         111414     111342        -72     
+ Misses        19238      19230         -8     
+ Partials       8972       8962        -10     

switch pi := piExpr.(type) {
case *ScalarFunction:
if pi.FuncName.L == ast.Plus || pi.FuncName.L == ast.Minus || pi.FuncName.L == ast.Mul || pi.FuncName.L == ast.Div {
left, right := pi.GetArgs()[0], pi.GetArgs()[1]
leftVal, ok, isNil := p.tryEvalPartitionExpr(left)
leftVal, ok, isNull := p.tryEvalPartitionExpr(left)
if !ok {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if !ok || isNull ?

expression/partition_pruner.go Outdated Show resolved Hide resolved
@tiancaiamao
Copy link
Contributor

LGTM
Please fix CI

@tiancaiamao tiancaiamao added the status/LGT1 Indicates that a PR has LGTM 1. label May 19, 2020
@imtbkcat
Copy link
Author

@tiancaiamao @XuHuaiyu PTAL

if err != nil {
return 0, false, false
} else if isNull {
return 0, true, true
}
return ret, true, false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return ret, true, isNull is enough?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, for expression like (year(null) + 2) or year(null), MySQL and TiDB both produce NULL

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what I mean is that:
we can remove line 140~141, and change line 143 to return ret, true, isNull

"explain select * from t4 where d = '2019-10-07 10:40:00' and a = 1",
"explain select * from t5 where d = '2019-10-07'"
"explain select * from t5 where d = '2019-10-07'",
"explain select * from t6 where a is null",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a case for explain select * from t6 where b is null

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done, PTAL

Copy link
Contributor

@XuHuaiyu XuHuaiyu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@XuHuaiyu
Copy link
Contributor

/merge

@sre-bot sre-bot added the status/can-merge Indicates a PR has been approved by a committer. label May 20, 2020
@XuHuaiyu XuHuaiyu added status/LGT2 Indicates that a PR has LGTM 2. and removed status/LGT1 Indicates that a PR has LGTM 1. labels May 20, 2020
@sre-bot
Copy link
Contributor

sre-bot commented May 20, 2020

/run-all-tests

@sre-bot
Copy link
Contributor

sre-bot commented May 20, 2020

@imtbkcat merge failed.

@imtbkcat
Copy link
Author

/merge

@sre-bot
Copy link
Contributor

sre-bot commented May 20, 2020

/run-all-tests

@XuHuaiyu
Copy link
Contributor

/merge

@sre-bot
Copy link
Contributor

sre-bot commented May 20, 2020

Your auto merge job has been accepted, waiting for:

  • 17195

@sre-bot
Copy link
Contributor

sre-bot commented May 20, 2020

/run-all-tests

@sre-bot sre-bot merged commit f17da4a into pingcap:master May 20, 2020
sre-bot pushed a commit to sre-bot/tidb that referenced this pull request May 20, 2020
Signed-off-by: sre-bot <sre-bot@pingcap.com>
@sre-bot
Copy link
Contributor

sre-bot commented May 20, 2020

cherry pick to release-3.0 in PR #17308

sre-bot pushed a commit to sre-bot/tidb that referenced this pull request May 20, 2020
Signed-off-by: sre-bot <sre-bot@pingcap.com>
@sre-bot
Copy link
Contributor

sre-bot commented May 20, 2020

cherry pick to release-3.1 in PR #17309

@sre-bot
Copy link
Contributor

sre-bot commented May 20, 2020

cherry pick to release-4.0 in PR #17310

ti-srebot added a commit that referenced this pull request Jun 28, 2020
#17308)

* cherry pick #17281 to release-3.0

Signed-off-by: sre-bot <sre-bot@pingcap.com>

* fix conflict

* fix ci

Co-authored-by: Lingyu Song <songlingyu@pingcap.com>
Co-authored-by: tiancaiamao <tiancaiamao@gmail.com>
Co-authored-by: ti-srebot <66930949+ti-srebot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component/expression sig/planner SIG: Planner status/can-merge Indicates a PR has been approved by a committer. status/LGT2 Indicates that a PR has LGTM 2. type/bugfix This PR fixes a bug.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants