| 586 | |
| 587 | == WARNING: SQL User Variables == |
| 588 | |
| 589 | The MySQL Reference manual warns explicitly |
| 590 | |
| 591 | {{{ |
| 592 | As a general rule, other than in SET statements, you should never assign a value to a user variable and read the value within the same statement. |
| 593 | }}} |
| 594 | |
| 595 | This is explain in the manual in more details here: https://dev.mysql.com/doc/refman/8.0/en/user-variables.html |
| 596 | |
| 597 | So generally speaking, the above example is supposed to FAIL! (...and works only by chance...) |
| 598 | |
| 599 | I have kept that here for convenience (and with the current server, it works, simply because the optimizer does not shuffle the columns. |
| 600 | |
| 601 | Now let's have a look at how the query should look correctly ('''Don't panic!'''): |
| 602 | |
| 603 | {{{ |
| 604 | SELECT |
| 605 | Counter.*, |
| 606 | `Signal` - `Background`/5 AS `Excess`, |
| 607 | LiMa(`Signal`, `Background`/5) AS `Significance` |
| 608 | FROM |
| 609 | ( |
| 610 | |
| 611 | SELECT |
| 612 | COUNT(IF(Weight>0, 1, NULL)) AS `Signal`, |
| 613 | COUNT(IF(Weight<0, 1, NULL)) AS `Background` |
| 614 | FROM |
| 615 | ( |
| 616 | SELECT |
| 617 | Weight, |
| 618 | (Disp*Disp + Dist*Dist - 2*Disp*Dist*SQRT(1-LX*LX)) AS ThetaSq |
| 619 | FROM |
| 620 | ( |
| 621 | SELECT |
| 622 | Weight, Dist, LX, |
| 623 | IF (SIGN(Sign1)<0 || SIGN(Sign2)<0, -Xi, Xi) * (1-WL) AS Disp |
| 624 | FROM |
| 625 | ( |
| 626 | SELECT |
| 627 | Weight, WL, Dist, LX, |
| 628 | 1.39252 + 0.154247*Slope + 1.67972*(1-1/(1+4.86232*Leakage1)) AS Xi, |
| 629 | M3L+0.07 AS Sign1, |
| 630 | (Dist-0.5)*7.2-Slope AS Sign2 |
| 631 | FROM |
| 632 | ( |
| 633 | SELECT |
| 634 | Weight, Leakage1, Dist, WL, LX, |
| 635 | M3Long*Sign*0.0117193246260285378 AS M3L, |
| 636 | SlopeLong*Sign/0.0117193246260285378 AS Slope |
| 637 | FROM |
| 638 | ( |
| 639 | SELECT |
| 640 | Weight, M3Long, SlopeLong, Leakage1, Dist, WL, LX, |
| 641 | ASIN(LX) AS Alpha, |
| 642 | SIGN(LY) AS Sign |
| 643 | FROM |
| 644 | ( |
| 645 | SELECT |
| 646 | Weight, M3Long, SlopeLong, Leakage1, Dist, WL, |
| 647 | TRUNCATE((CosDelta*DY - SinDelta*DX)/Norm, 6) AS LX, |
| 648 | TRUNCATE((CosDelta*DX + SinDelta*DY)/Norm, 6) AS LY |
| 649 | FROM |
| 650 | ( |
| 651 | SELECT |
| 652 | Weight, CosDelta, SinDelta, DX, DY, M3Long, SlopeLong, Leakage1, WL, |
| 653 | SQRT(DX*DX + DY*DY) AS Norm, |
| 654 | SQRT(DX*DX + DY*DY)*0.0117193246260285378 AS Dist |
| 655 | FROM |
| 656 | ( |
| 657 | SELECT |
| 658 | Weight, CosDelta, SinDelta, M3Long, SlopeLong, Leakage1, WL, |
| 659 | MeanX - PX/1.02 AS DX, |
| 660 | MeanY - PY/1.02 AS DY |
| 661 | FROM |
| 662 | ( |
| 663 | SELECT |
| 664 | Weight, MeanX, MeanY, CosDelta, SinDelta, M3Long, SlopeLong, Leakage1, WL, |
| 665 | cosa*X - sina*Y/1.02 AS PX, |
| 666 | cosa*Y + sina*X/1.02 AS PY |
| 667 | FROM |
| 668 | ( |
| 669 | SELECT |
| 670 | Weight, |
| 671 | Size, |
| 672 | NumUsedPixels, |
| 673 | NumIslands, |
| 674 | Leakage1, |
| 675 | MeanX, |
| 676 | MeanY, |
| 677 | CosDelta, |
| 678 | SinDelta, |
| 679 | M3Long, |
| 680 | SlopeLong, |
| 681 | Width/Length AS WL, |
| 682 | PI()*Width*Length AS Area, |
| 683 | cosa, |
| 684 | sina, |
| 685 | X, |
| 686 | Y |
| 687 | FROM RunInfo |
| 688 | LEFT JOIN Events USING (FileId) |
| 689 | LEFT JOIN Position USING (FileId, EvtNumber) |
| 690 | CROSS JOIN Wobble |
| 691 | WHERE |
| 692 | fSourceKey=5 |
| 693 | AND |
| 694 | fRunTypeKey=1 |
| 695 | AND |
| 696 | FileId BETWEEN 131101000 AND 131107000 |
| 697 | AND |
| 698 | fZenithDistanceMax<35 |
| 699 | AND |
| 700 | fR750Cor>0.9*fR750Ref |
| 701 | AND |
| 702 | NumUsedPixels>5.5 |
| 703 | AND |
| 704 | NumIslands<3.5 |
| 705 | AND |
| 706 | Leakage1<0.1 |
| 707 | HAVING |
| 708 | Area < LOG10(Size)*898-1535 |
| 709 | |
| 710 | ) Inner0 |
| 711 | |
| 712 | ) Inner1 |
| 713 | |
| 714 | ) Inner2 |
| 715 | |
| 716 | ) Inner3 |
| 717 | |
| 718 | ) Inner4 |
| 719 | |
| 720 | ) Inner5 |
| 721 | |
| 722 | ) Inner6 |
| 723 | |
| 724 | ) Inner7 |
| 725 | |
| 726 | ) Table8 |
| 727 | |
| 728 | HAVING |
| 729 | ThetaSq<0.024 |
| 730 | |
| 731 | ) Table9 |
| 732 | |
| 733 | ) Counter |
| 734 | |
| 735 | }}} |
| 736 | |
| 737 | Now what makes the difference... first, execution time shows the power of MySQL. The old query leads: |
| 738 | {{{ |
| 739 | Execution time: 122.145s |
| 740 | }}} |
| 741 | |
| 742 | This new query results in |
| 743 | {{{ |
| 744 | Execution time: 21.3579s |
| 745 | }}} |
| 746 | |
| 747 | Why is this so much faster? I guess it has two reasons: |
| 748 | |
| 749 | 1) Only variables which are really needed in the next step are kept (reduces memory consumption) |
| 750 | 2) Cuts are evaluated by the optimizer as soon as possible (e.g. the Area cuts might be evaluated even before the other values are loaded from disk) |
| 751 | |
| 752 | Another example (apart from the obvious difficulty to read the query) is that it is very well structured. For each step it is very well defined what values |
| 753 | are available from the previous step (the fields which are requested in each SELECT statement) and it is very well defined in which order the algorithm is executed. |