2017-03-23 1 views
0

ich derzeit Daten von Percona 5.5.14 bis MariaDB 10.1.22MariaDB: Kraft „SELECT STRAIGHT_JOIN“ als Standardparameter

auf eine bestimmte Abfrage Wich wandern wird mit einigen JOIN, Abfrage-Plan unterscheidet sich zwischen den zwei Versionen und Reaktionszeit> 400 ms

Die einzige Lösung, die ich gefunden habe, dies zu lösen ist STRAIGHT_JOIN Option zu verwenden:

Percona 5.5.14 => 150 ms

MariaDB 10.1.22 => 550ms ==> 150 ms Mit Option STRAIGHT_JOIN

Meine Frage ist: Gibt es einen Parameter, um die Option STRAIGHT_JOIN bei jeder SELECT-Abfrage, die JOINs verwendet, zu erzwingen?

Ich verstehe, es ist keine gute Lösung, aber ich möchte wissen, ob es existiert, weil ich es nicht


Rückfrage in einer gespeicherten Prozedur ist gefunden:

SELECT 
      C.NAME      AS out_Name, 
      RC.ID      AS out_PlanId, 
      ISO.A3      AS out_A3, 
      ISO.NAME     AS out_CountryName, 
      ISO.NUMBER     AS out_countryNumber, 
      C.ID      AS out_CId, 
      RC.NAME      AS out_CName, 
      RSG.NAME     AS out_ServiceGroupName, 
      SPE.id      AS out_EntryId, 
      SPE.GOUPID     AS out_GroupId, 
      ZPE.ZONEID     AS out_zoneId, 
      Z.NAME      AS out_zoneName,    
      ZPE.ID      AS out_zoneEntryId, 
      ZPE.PREFIX     AS out_zonePrefix, 
      RC.PLANID     AS out_zonePlanId, 
      SPE.ZONEID     AS out_zoneGroupId, 
      ZSG.NAME     AS out_zoneGroupName, 
      SCPA.ID      AS out_scpAId, 
      SCPA.NAME     AS out_scpAName, 
      ZG.ID      AS out_zoningpId, 
      ZG.NAME      AS out_zoningName, 
      IFNULL(SF1.NAME,"")   AS out_Flag_serviceType_name, 
      IFNULL(SF2.NAME,"")   AS out_Flag_service_name, 
      IFNULL(SF3.NAME,"")   AS out_Flag_zone_name, 
      IFNULL(SF4.NAME,"")   AS out_Flag_Plan_name, 
      RC.RULEID     AS out_ruleId, 
      RP.NAME      AS out_ruleName 
    FROM 
      table1      AS M , 
      table2      AS C, 
      table3      AS RC, 
      table3      AS RP, 
      table4      AS SPE LEFT JOIN table12 AS SF2 ON SF2.id=SPE.FLAGID, 
      table5      AS ST LEFT JOIN table11 AS SF1 ON SF1.id=ST.FLAGID, 
      table6      AS RSG, 
      table7      AS ZSG, 
      table8      AS ZPE LEFT JOIN table14 as SF4 on SF4.id=ZPE.FLAGID, 
      table9      AS ISO, 
      table10      AS NP, 
      table11      AS Z LEFT JOIN table13 as SF3 on SF3.id=Z.FLAGID , 
      table12      AS SCPA, 
      table13      AS ZG 
    WHERE 
      M.name       ='TSL' 
      AND C.mvno_id     =M.id 
      AND C.id      ='1010' 
      AND RC.id      =C.ID 
      AND RP.id      =RC.RULEID 
      AND SPE.SERVICEID    =RC.SERVICEID 
      AND RSG.ID      =SPE.GOUP_ID 
      AND ST.NAME      ='GOR' 
      AND SPE.SERVICETYPE_ID   =ST.ID 
      AND ZSG.ID      =SPE.ZONEID 
      AND ZPE.ZONE_PLAN_ID   =RC.PLANID 
      AND NP.NAME      ='OSI' 
      AND ZPE.NUMBERINGPLAN_ID  =NP.ID 
      AND ZPE.ISOCOUNTRY_ID   =ISO.ID 
      AND ZPE.ZONEID     =ZSG.ID 
      AND Z.ID      =ZPE.ZONEID 
      AND SCPA.ID      =Z.ACTIONID 
      AND ZG.ID      =Z.GROUPID 
      AND ZSG.ID      =ZPE.ZONEID 
      AND UNIX_TIMESTAMP() 
        BETWEEN UNIX_TIMESTAMP(IFNULL(ZPE.VALIDFROM,0)) 
         AND UNIX_TIMESTAMP(IFNULL(ZPE.VALIDUNTIL,"2038-01-01"))    
      AND (
        (
         '0'=0 
         AND ZPE.PREFIX  ='AUT' 
        ) 
       OR 
        ( '0'=1 
         AND 
         (
           substring('AUT',1,1)=ZPE.prefix 
          OR substring('AUT',1,2)=ZPE.prefix 
          OR substring('AUT',1,3)=ZPE.prefix 
          OR substring('AUT',1,4)=ZPE.prefix 
          OR substring('AUT',1,5)=ZPE.prefix 
          OR substring('AUT',1,6)=ZPE.prefix 
          OR substring('AUT',1,7)=ZPE.prefix 
          OR substring('AUT',1,8)=ZPE.prefix 
          OR substring('AUT',1,9)=ZPE.prefix 
          OR substring('AUT',1,10)=ZPE.prefix 
          OR substring('AUT',1,11)=ZPE.prefix 
          OR substring('AUT',1,12)=ZPE.prefix 
          OR substring('AUT',1,13)=ZPE.prefix 
          OR substring('AUT',1,14)=ZPE.prefix 
          OR substring('AUT',1,15)=ZPE.prefix 
          OR concat('AUT','#') =ZPE.prefix 
         ) 
        ) 
      ) 
    ORDER BY LENGTH(prefix) DESC 
    LIMIT 1; 

EXPLAIN MariaDB

EXPLAIN IN PRODUCTION (Percona)

+0

Ich glaube nicht, dass es ein Weg, um Auto-SJ ist. Möchten Sie uns eine der Abfragen zeigen, plus 'EXPLAIN' (vorzugsweise auf beiden Servern) und' SHOW CREATE TABLE'. Es kann eine andere Technik geben, um die Geschwindigkeit wiederzuerlangen. –

+0

Danke für Ihre Antwort. Für Informationen ist es ein Aufruf der gespeicherten Prozedur in Schleife (x100) – JonGo

Antwort

0

Put parenthese s um die LEFT JOINs um sicherzustellen, dass sie korrekt und das gleiche von den beiden Versionen analysiert werden:

(table4 AS SPE LEFT JOIN table12 AS SF2 ON SF2.id=SPE.FLAGID), 
(table5 AS ST LEFT JOIN table11 AS SF1 ON SF1.id=ST.FLAGID ), 

Zur gleichen Zeit die JOINs weg von „commajoin“ zu JOIN .. ON ändern. Das wird das Lesen erleichtern. Und besonders, machen deutlich, was in den WHERE ist.

Da Sie offensichtlich die SQL generieren, arbeiten nur ein wenig härter Konstrukte wie '0'=1 zu vermeiden.

Ist nicht substring('AUT',1,1)=ZPE.prefix OR substring('AUT',1,2)=ZPE.prefix OR ... einfacher als ZPE.prefix = left('AUT', CHAR_LENGTH(ZPE.prefix geschrieben)) ? Once you have change to that, you can probably further simplify that expression, probably getting rid of the other side of the ODER , and perhaps allowing INDEX (Präfix) `nützlich sein.

Beachten Sie, dass LENGTH() die Byte Länge ist; CHAR_LENGTH() ist die Charakter Länge.

Alle Ihre IDs sind BIGINT? Brauchst du wirklich so viel Auswahl? Durch das Verkleinern des Datentyps wird die Leistung verbessert.

Ich sehe Using intersect. Bitte geben Sie SHOW CREATE TABLE ZPE an, damit wir sehen können, was vor sich geht. Normalerweise, dass die Optimierung ist nicht so gut wie mit einem 'Composite' Index.

Ich weiß, dass ich die Frage, die Sie gestellt haben, nicht beantwortet habe. Aber ich würde lieber die oben genannten Aufräumarbeiten machen.