| | 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. |