@@ -37,6 +37,9 @@ import (
37
37
)
38
38
39
39
func (p * LogicalUnionScan ) exhaustPhysicalPlans (prop * property.PhysicalProperty ) []PhysicalPlan {
40
+ if prop .IsFlashOnlyProp () {
41
+ return nil
42
+ }
40
43
childProp := prop .Clone ()
41
44
us := PhysicalUnionScan {
42
45
Conditions : p .conditions ,
@@ -1416,11 +1419,26 @@ func (p *LogicalJoin) tryToGetIndexJoin(prop *property.PhysicalProperty) (indexJ
1416
1419
// If the hint is not matched, it will get other candidates.
1417
1420
// If the hint is not figured, we will pick all candidates.
1418
1421
func (p * LogicalJoin ) exhaustPhysicalPlans (prop * property.PhysicalProperty ) []PhysicalPlan {
1422
+ if prop .IsFlashOnlyProp () && ((p .preferJoinType & preferMergeJoin ) > 0 || (p .preferJoinType & preferHashJoin ) > 0 ) {
1423
+ return nil
1424
+ }
1425
+ joins := make ([]PhysicalPlan , 0 , 5 )
1426
+ if p .ctx .GetSessionVars ().AllowBCJ {
1427
+ broadCastJoins := p .tryToGetBroadCastJoin (prop )
1428
+ if (p .preferJoinType & preferBCJoin ) > 0 {
1429
+ logutil .BgLogger ().Info ("prefer bc join" , zap .Int ("bc count" , len (broadCastJoins )))
1430
+ return broadCastJoins
1431
+ }
1432
+ joins = append (joins , broadCastJoins ... )
1433
+ }
1434
+ if prop .IsFlashOnlyProp () {
1435
+ return joins
1436
+ }
1437
+
1419
1438
mergeJoins := p .GetMergeJoin (prop , p .schema , p .Stats (), p .children [0 ].statsInfo (), p .children [1 ].statsInfo ())
1420
1439
if (p .preferJoinType & preferMergeJoin ) > 0 {
1421
1440
return mergeJoins
1422
1441
}
1423
- joins := make ([]PhysicalPlan , 0 , 5 )
1424
1442
joins = append (joins , mergeJoins ... )
1425
1443
1426
1444
indexJoins , forced := p .tryToGetIndexJoin (prop )
@@ -1435,31 +1453,25 @@ func (p *LogicalJoin) exhaustPhysicalPlans(prop *property.PhysicalProperty) []Ph
1435
1453
return hashJoins
1436
1454
}
1437
1455
joins = append (joins , hashJoins ... )
1438
-
1439
- if p .ctx .GetSessionVars ().AllowBCJ {
1440
- broadCastJoins := p .tryToGetBroadCastJoin (prop )
1441
- joins = append (joins , broadCastJoins ... )
1442
- if (p .preferJoinType & preferBCJoin ) > 0 {
1443
- logutil .BgLogger ().Info ("prefer bc join" , zap .Int ("bc count" , len (broadCastJoins )))
1444
- return broadCastJoins
1445
- }
1446
- }
1447
1456
return joins
1448
1457
}
1449
1458
1450
- func (p * LogicalJoin ) tryToGetBroadCastJoin (prop * property.PhysicalProperty ) []PhysicalPlan {
1451
- child0 , ok0 := p .children [0 ].(* DataSource )
1452
- if ! ok0 {
1453
- return nil
1459
+ func getAllDataSourceRowCount (plan LogicalPlan ) int64 {
1460
+ if ds , ok := plan .(* DataSource ); ok {
1461
+ return ds .statsInfo ().Count ()
1454
1462
}
1455
- child1 , ok1 := p . children [ 1 ].( * DataSource )
1456
- if ! ok1 {
1457
- return nil
1463
+ ret := int64 ( 0 )
1464
+ for _ , child := range plan . Children () {
1465
+ ret += getAllDataSourceRowCount ( child )
1458
1466
}
1467
+ return ret
1468
+ }
1469
+
1470
+ func (p * LogicalJoin ) tryToGetBroadCastJoin (prop * property.PhysicalProperty ) []PhysicalPlan {
1459
1471
if ! prop .IsEmpty () {
1460
1472
return nil
1461
1473
}
1462
- if prop .TaskTp != property .RootTaskType && prop . TaskTp != property . CopTiFlashLocalReadTaskType && prop .TaskTp != property . CopTiFlashGlobalReadTaskType {
1474
+ if prop .TaskTp != property .RootTaskType && ! prop .IsFlashOnlyProp () {
1463
1475
return nil
1464
1476
}
1465
1477
@@ -1476,20 +1488,28 @@ func (p *LogicalJoin) tryToGetBroadCastJoin(prop * property.PhysicalProperty) []
1476
1488
LeftJoinKeys : lkeys ,
1477
1489
RightJoinKeys : rkeys ,
1478
1490
}
1479
- if child0 .stats .Count () < child1 .stats .Count () {
1491
+ // todo: currently, build side is the one has less rowcont and global read side
1492
+ // is the one has less datasource row count(which mean less remote read), need
1493
+ // to use cbo to decide the build side and global read side
1494
+ if p .children [0 ].statsInfo ().Count () < p .children [1 ].statsInfo ().Count () {
1480
1495
baseJoin .InnerChildIdx = 0
1481
1496
} else {
1482
1497
baseJoin .InnerChildIdx = 1
1483
1498
}
1499
+ globalIndex := baseJoin .InnerChildIdx
1500
+ if prop .TaskTp != property .CopTiFlashGlobalReadTaskType && getAllDataSourceRowCount (p .children [globalIndex ]) > getAllDataSourceRowCount (p .children [1 - globalIndex ]) {
1501
+ globalIndex = 1 - globalIndex
1502
+ }
1484
1503
childrenReqProps := make ([]* property.PhysicalProperty , 2 )
1485
- childrenReqProps [baseJoin . InnerChildIdx ] = & property.PhysicalProperty {TaskTp : property .CopTiFlashGlobalReadTaskType }
1504
+ childrenReqProps [globalIndex ] = & property.PhysicalProperty {TaskTp : property .CopTiFlashGlobalReadTaskType }
1486
1505
if prop .TaskTp == property .CopTiFlashGlobalReadTaskType {
1487
- childrenReqProps [1 - baseJoin . InnerChildIdx ] = & property.PhysicalProperty {TaskTp : property .CopTiFlashGlobalReadTaskType }
1506
+ childrenReqProps [1 - globalIndex ] = & property.PhysicalProperty {TaskTp : property .CopTiFlashGlobalReadTaskType }
1488
1507
} else {
1489
- childrenReqProps [1 - baseJoin . InnerChildIdx ] = & property.PhysicalProperty {TaskTp : property .CopTiFlashLocalReadTaskType }
1508
+ childrenReqProps [1 - globalIndex ] = & property.PhysicalProperty {TaskTp : property .CopTiFlashLocalReadTaskType }
1490
1509
}
1491
1510
join := PhysicalBroadCastJoin {
1492
1511
basePhysicalJoin : baseJoin ,
1512
+ globalChildIndex : globalIndex ,
1493
1513
}.Init (p .ctx , p .stats , p .blockOffset , childrenReqProps ... )
1494
1514
results := make ([]PhysicalPlan , 0 , 1 )
1495
1515
results = append (results , join )
@@ -1500,6 +1520,9 @@ func (p *LogicalJoin) tryToGetBroadCastJoin(prop * property.PhysicalProperty) []
1500
1520
// When a sort column will be replaced by scalar function, we refuse it.
1501
1521
// When a sort column will be replaced by a constant, we just remove it.
1502
1522
func (p * LogicalProjection ) TryToGetChildProp (prop * property.PhysicalProperty ) (* property.PhysicalProperty , bool ) {
1523
+ if prop .IsFlashOnlyProp () {
1524
+ return nil , false
1525
+ }
1503
1526
newProp := & property.PhysicalProperty {TaskTp : property .RootTaskType , ExpectedCnt : prop .ExpectedCnt }
1504
1527
newCols := make ([]property.Item , 0 , len (prop .Items ))
1505
1528
for _ , col := range prop .Items {
@@ -1529,9 +1552,10 @@ func (p *LogicalProjection) exhaustPhysicalPlans(prop *property.PhysicalProperty
1529
1552
return []PhysicalPlan {proj }
1530
1553
}
1531
1554
1532
- func (lt * LogicalTopN ) getPhysTopN () []PhysicalPlan {
1533
- ret := make ([]PhysicalPlan , 0 , 3 )
1534
- for _ , tp := range wholeTaskTypes {
1555
+ func (lt * LogicalTopN ) getPhysTopN (prop * property.PhysicalProperty ) []PhysicalPlan {
1556
+ allTaskTypes := prop .GetAllPossibleChildTaskTypes ()
1557
+ ret := make ([]PhysicalPlan , 0 , len (allTaskTypes ))
1558
+ for _ , tp := range allTaskTypes {
1535
1559
resultProp := & property.PhysicalProperty {TaskTp : tp , ExpectedCnt : math .MaxFloat64 }
1536
1560
topN := PhysicalTopN {
1537
1561
ByItems : lt .ByItems ,
@@ -1543,14 +1567,15 @@ func (lt *LogicalTopN) getPhysTopN() []PhysicalPlan {
1543
1567
return ret
1544
1568
}
1545
1569
1546
- func (lt * LogicalTopN ) getPhysLimits () []PhysicalPlan {
1547
- prop , canPass := GetPropByOrderByItems (lt .ByItems )
1570
+ func (lt * LogicalTopN ) getPhysLimits (prop * property. PhysicalProperty ) []PhysicalPlan {
1571
+ p , canPass := GetPropByOrderByItems (lt .ByItems )
1548
1572
if ! canPass {
1549
1573
return nil
1550
1574
}
1575
+ allTaskTypes := prop .GetAllPossibleChildTaskTypes ()
1551
1576
ret := make ([]PhysicalPlan , 0 , 3 )
1552
- for _ , tp := range wholeTaskTypes {
1553
- resultProp := & property.PhysicalProperty {TaskTp : tp , ExpectedCnt : float64 (lt .Count + lt .Offset ), Items : prop .Items }
1577
+ for _ , tp := range allTaskTypes {
1578
+ resultProp := & property.PhysicalProperty {TaskTp : tp , ExpectedCnt : float64 (lt .Count + lt .Offset ), Items : p .Items }
1554
1579
limit := PhysicalLimit {
1555
1580
Count : lt .Count ,
1556
1581
Offset : lt .Offset ,
@@ -1562,7 +1587,7 @@ func (lt *LogicalTopN) getPhysLimits() []PhysicalPlan {
1562
1587
1563
1588
// MatchItems checks if this prop's columns can match by items totally.
1564
1589
func MatchItems (p * property.PhysicalProperty , items []* ByItems ) bool {
1565
- if len (items ) < len (p .Items ) {
1590
+ if len (items ) < len (p .Items ) || p . IsFlashOnlyProp () {
1566
1591
return false
1567
1592
}
1568
1593
for i , col := range p .Items {
@@ -1576,7 +1601,7 @@ func MatchItems(p *property.PhysicalProperty, items []*ByItems) bool {
1576
1601
1577
1602
func (lt * LogicalTopN ) exhaustPhysicalPlans (prop * property.PhysicalProperty ) []PhysicalPlan {
1578
1603
if MatchItems (prop , lt .ByItems ) {
1579
- return append (lt .getPhysTopN (), lt .getPhysLimits ()... )
1604
+ return append (lt .getPhysTopN (prop ), lt .getPhysLimits (prop )... )
1580
1605
}
1581
1606
return nil
1582
1607
}
@@ -1587,7 +1612,7 @@ func (la *LogicalApply) GetHashJoin(prop *property.PhysicalProperty) *PhysicalHa
1587
1612
}
1588
1613
1589
1614
func (la * LogicalApply ) exhaustPhysicalPlans (prop * property.PhysicalProperty ) []PhysicalPlan {
1590
- if ! prop .AllColsFromSchema (la .children [0 ].Schema ()) { // for convenient, we don't pass through any prop
1615
+ if ! prop .AllColsFromSchema (la .children [0 ].Schema ()) || prop . IsFlashOnlyProp () { // for convenient, we don't pass through any prop
1591
1616
return nil
1592
1617
}
1593
1618
join := la .GetHashJoin (prop )
@@ -1604,6 +1629,9 @@ func (la *LogicalApply) exhaustPhysicalPlans(prop *property.PhysicalProperty) []
1604
1629
}
1605
1630
1606
1631
func (p * LogicalWindow ) exhaustPhysicalPlans (prop * property.PhysicalProperty ) []PhysicalPlan {
1632
+ if prop .IsFlashOnlyProp () {
1633
+ return nil
1634
+ }
1607
1635
var byItems []property.Item
1608
1636
byItems = append (byItems , p .PartitionBy ... )
1609
1637
byItems = append (byItems , p .OrderBy ... )
@@ -1637,8 +1665,12 @@ func (la *LogicalAggregation) canPushToCop() bool {
1637
1665
}
1638
1666
1639
1667
func (la * LogicalAggregation ) getEnforcedStreamAggs (prop * property.PhysicalProperty ) []PhysicalPlan {
1668
+ if prop .IsFlashOnlyProp () {
1669
+ return nil
1670
+ }
1640
1671
_ , desc := prop .AllSameOrder ()
1641
- enforcedAggs := make ([]PhysicalPlan , 0 , len (wholeTaskTypes ))
1672
+ allTaskTypes := prop .GetAllPossibleChildTaskTypes ()
1673
+ enforcedAggs := make ([]PhysicalPlan , 0 , len (allTaskTypes ))
1642
1674
childProp := & property.PhysicalProperty {
1643
1675
ExpectedCnt : math .Max (prop .ExpectedCnt * la .inputCount / la .stats .RowCount , prop .ExpectedCnt ),
1644
1676
Enforced : true ,
@@ -1665,6 +1697,10 @@ func (la *LogicalAggregation) getEnforcedStreamAggs(prop *property.PhysicalPrope
1665
1697
}
1666
1698
1667
1699
func (la * LogicalAggregation ) getStreamAggs (prop * property.PhysicalProperty ) []PhysicalPlan {
1700
+ // todo support CopTiFlash task type in stream agg
1701
+ if prop .IsFlashOnlyProp () {
1702
+ return nil
1703
+ }
1668
1704
all , desc := prop .AllSameOrder ()
1669
1705
if ! all {
1670
1706
return nil
@@ -1680,7 +1716,8 @@ func (la *LogicalAggregation) getStreamAggs(prop *property.PhysicalProperty) []P
1680
1716
return nil
1681
1717
}
1682
1718
1683
- streamAggs := make ([]PhysicalPlan , 0 , len (la .possibleProperties )* (len (wholeTaskTypes )- 1 )+ len (wholeTaskTypes ))
1719
+ allTaskTypes := prop .GetAllPossibleChildTaskTypes ()
1720
+ streamAggs := make ([]PhysicalPlan , 0 , len (la .possibleProperties )* (len (allTaskTypes )- 1 )+ len (allTaskTypes ))
1684
1721
childProp := & property.PhysicalProperty {
1685
1722
ExpectedCnt : math .Max (prop .ExpectedCnt * la .inputCount / la .stats .RowCount , prop .ExpectedCnt ),
1686
1723
}
@@ -1721,11 +1758,14 @@ func (la *LogicalAggregation) getHashAggs(prop *property.PhysicalProperty) []Phy
1721
1758
if ! prop .IsEmpty () {
1722
1759
return nil
1723
1760
}
1724
- hashAggs := make ([]PhysicalPlan , 0 , len (wholeTaskTypes ))
1725
- taskTypes := []property.TaskType {property .CopSingleReadTaskType , property .CopDoubleReadTaskType , property .CopTiFlashLocalReadTaskType , property . CopTiFlashGlobalReadTaskType }
1761
+ hashAggs := make ([]PhysicalPlan , 0 , len (prop . GetAllPossibleChildTaskTypes () ))
1762
+ taskTypes := []property.TaskType {property .CopSingleReadTaskType , property .CopDoubleReadTaskType , property .CopTiFlashLocalReadTaskType }
1726
1763
if ! la .aggHints .preferAggToCop {
1727
1764
taskTypes = append (taskTypes , property .RootTaskType )
1728
1765
}
1766
+ if prop .IsFlashOnlyProp () {
1767
+ taskTypes = []property.TaskType {prop .TaskTp }
1768
+ }
1729
1769
for _ , taskTp := range taskTypes {
1730
1770
agg := NewPhysicalHashAgg (la , la .stats .ScaleByExpectCnt (prop .ExpectedCnt ), & property.PhysicalProperty {ExpectedCnt : math .MaxFloat64 , TaskTp : taskTp })
1731
1771
agg .SetSchema (la .schema .Clone ())
@@ -1795,8 +1835,9 @@ func (p *LogicalLimit) exhaustPhysicalPlans(prop *property.PhysicalProperty) []P
1795
1835
if ! prop .IsEmpty () {
1796
1836
return nil
1797
1837
}
1798
- ret := make ([]PhysicalPlan , 0 , len (wholeTaskTypes ))
1799
- for _ , tp := range wholeTaskTypes {
1838
+ allTaskTypes := prop .GetAllPossibleChildTaskTypes ()
1839
+ ret := make ([]PhysicalPlan , 0 , len (allTaskTypes ))
1840
+ for _ , tp := range allTaskTypes {
1800
1841
resultProp := & property.PhysicalProperty {TaskTp : tp , ExpectedCnt : float64 (p .Count + p .Offset )}
1801
1842
limit := PhysicalLimit {
1802
1843
Offset : p .Offset ,
@@ -1808,6 +1849,9 @@ func (p *LogicalLimit) exhaustPhysicalPlans(prop *property.PhysicalProperty) []P
1808
1849
}
1809
1850
1810
1851
func (p * LogicalLock ) exhaustPhysicalPlans (prop * property.PhysicalProperty ) []PhysicalPlan {
1852
+ if prop .IsFlashOnlyProp () {
1853
+ return nil
1854
+ }
1811
1855
childProp := prop .Clone ()
1812
1856
lock := PhysicalLock {
1813
1857
Lock : p .Lock ,
@@ -1819,7 +1863,7 @@ func (p *LogicalLock) exhaustPhysicalPlans(prop *property.PhysicalProperty) []Ph
1819
1863
1820
1864
func (p * LogicalUnionAll ) exhaustPhysicalPlans (prop * property.PhysicalProperty ) []PhysicalPlan {
1821
1865
// TODO: UnionAll can not pass any order, but we can change it to sort merge to keep order.
1822
- if ! prop .IsEmpty () {
1866
+ if ! prop .IsEmpty () || prop . IsFlashOnlyProp () {
1823
1867
return nil
1824
1868
}
1825
1869
chReqProps := make ([]* property.PhysicalProperty , 0 , len (p .children ))
@@ -1860,7 +1904,7 @@ func (ls *LogicalSort) exhaustPhysicalPlans(prop *property.PhysicalProperty) []P
1860
1904
}
1861
1905
1862
1906
func (p * LogicalMaxOneRow ) exhaustPhysicalPlans (prop * property.PhysicalProperty ) []PhysicalPlan {
1863
- if ! prop .IsEmpty () {
1907
+ if ! prop .IsEmpty () || prop . IsFlashOnlyProp () {
1864
1908
return nil
1865
1909
}
1866
1910
mor := PhysicalMaxOneRow {}.Init (p .ctx , p .stats , p .blockOffset , & property.PhysicalProperty {ExpectedCnt : 2 })
0 commit comments