2017-08-03 4 views
3

Also zunächst sind meine MySQL-Tabelle wie folgt definiert:Mysql - zu viel Zeit, um Abfragen auszuführen

Orders (333000+ records)

orders_id(PK), 
customerName, 
CompanyName, 
Status, 
shipping_no, 
shipping_module, 
tracking_no, 
orders_status, 
date_purchased.. 

order_status (70 Einträge)

orders_status_id(pk), 
language_id, 
orders_status_name 

orders_status_history (2220000+ r ecords)

`orders_status_history_id` int(11) 
    `orders_id` int(11) 
    `orders_status_id` int(5) 
    PRIMARY KEY (`orders_status_history_id`) 

orders_status_history Tabelle enthält verschiedene Status über alle Aufträge

`orders_status_id` int(11) 
    `orders_status_name` varchar(32) 
    PRIMARY KEY (`orders_status_id`,`language_id`) 

Also, was ich versuche zu bekommen, dass alle drei Optionen unten beschrieben:

  1. Orders haben muss shipping_module pickup_pickup oder pickup2_pickup2
  2. orders_status_history.orders_status_id Muss folgenden Status 7, 21, 34, 40
  3. Aber orders_status_history.orders_status_id folgende Darf NICHT Status 33,53

Erklären Problem haben haben: Angenommen gibt es 10 Aufträge, und sie haben die folgenden auf einige Status hatten Zeit in ihrem Leben:

  1. [7, 34, 41,48]
  2. [20, 40, 34, 57, 14, 25]
  3. [53,7,40,5]
  4. [41,25,4]
  5. [1,2,3,4]
  6. [34,4,33,53,7]
  7. [4,21,31,7,8]
  8. [78,15,45,40]
  9. [53,40,31,21,7]
  10. [33,74,54,7,22]

So Aufträge, die ich will, zu extrahieren sind 1,2,7,8, weil diese Bestellungen 7,31,21 oder 40 und nicht 53, 33

enthalten

Ich habe versucht, folgende Anfragen:

1.)

SELECT * 
FROM orders AS o, orders_status_history AS osh 
WHERE (
     o.shipping_module LIKE '%pickup_pickup%' 
     OR o.shipping_module LIKE '%pickup2_pickup2%' 
    ) 
AND o.orders_id = osh.orders_id 
AND osh.orders_status_id 
IN (7, 21, 31, 40) AND osh.orders_status_id 
NOT IN (33, 53) 

Diese Abfrage funktioniert als Leistung ok, aber alles Ergebnis (1200 Datensätze) bekommen, aber es hat nicht filtern 3 Option

2 .)

SELECT * 
FROM orders AS o, orders_status_history AS osh 
WHERE (
     o.shipping_module LIKE '%pickup_pickup%' 
     OR o.shipping_module LIKE '%pickup2_pickup2%' 
    ) 
AND o.orders_id = osh.orders_id 
AND osh.orders_status_id IN (7, 21, 31, 40) 
AND osh.orders_status_id != 33 
AND osh.orders_status_id != 53 

Es funktioniert auch als vorherige, nur knapp sein Ziel Filter 3. Option

3.)

SELECT * 
FROM orders AS o, orders_status_history AS osh 
WHERE (
     o.shipping_module LIKE '%pickup_pickup%' 
     OR o.shipping_module LIKE '%pickup2_pickup2%' 
    ) 
AND o.orders_id = osh.orders_id 
AND osh.orders_status_id IN (7, 21, 31, 40) 
AND osh.orders_status_id NOT IN (
           SELECT so.orders_id 
           FROM orders AS so, orders_status_history AS sosh 
           WHERE (
             so.shipping_module LIKE '%pickup_pickup%' 
             OR so.shipping_module LIKE '%pickup2_pickup2%' 
             ) 
           AND sosh.orders_status_id != 33 
          ) 

Diese Abfrage zu viel Zeit für die Ausführung nahm und nicht

4 hat excute .)

SELECT * 
FROM orders AS o, orders_status_history AS osh 
WHERE (
     o.shipping_module LIKE '%pickup_pickup%' 
     OR o.shipping_module LIKE '%pickup2_pickup2%' 
    ) 
AND o.orders_id = osh.orders_id 
AND osh.orders_status_id = 7 
AND osh.orders_status_id = 21 
AND osh.orders_status_id = 31 
AND osh.orders_status_id = 40 
AND osh.orders_status_id != 33 
AND osh.orders_status_id != 53 

Diese Abfrage funktioniert als erste zu Abfragen nicht 3. Option

Filter hat also später versuchte ich es mit php

$sql = "SELECT o.orders_id, osh.orders_status_history_id 
     FROM 
      orders AS o, 
      orders_status_history AS osh 
     WHERE ( 
      o.shipping_module LIKE '%pickup_pickup%' 
      OR o.shipping_module LIKE '%pickup2_pickup2%' 
      ) 
     AND o.orders_id = osh.orders_id 
     AND osh.orders_status_id IN (7, 21, 31, 40) 
     AND osh.orders_status_id != 33 
     AND osh.orders_status_id != 53"; 
$sql = mysql_query($sql); 
while ($row = mysql_fetch_array($sql)){ 
    $row["orders_id"]); 
    if(getOrderStatus($row["orders_id"])) 
     echo "<br/>".$row["orders_id"]; 
} 

function getOrderStatus($order){ 
    $sql = "SELECT orders_status_id FROM orders_status_history WHERE orders_id = ".$order; 
    echo "<br/> Sql Query : ".$sql; 
    $sql = mysql_query($sql); 
    while ($status  = mysql_fetch_array($sql)) 
     if((int)$status["orders_status_id"] == 33 || (int)$status["orders_status_id"] == 53) 
      return false; 
    return true; 
} 

Dieser Code wurde zu viel Zeit in Anspruch als 30m mehr nehmen. Ich set_time_limit(0);

Hinweis: kann ich nur mysql_ verwenden *, weil unsere PHP-Version ist 4.9

+2

Neben PHP 4.9 wirklich veraltet ist (Sie sollten Ihren Chef beraten zu aktualisieren), haben Sie jemals laufen ' ERKLÄREN ... 'auf deinen Fragen? Welche Art von Indizes sind für die Tabellen festgelegt? – Paul

+2

'osh.orders_status_id IN (7, 21, 31, 40) UND osh.orders_status_id NOT IN (33, 53)' ergibt keinen Sinn, als wäre etwas (7, 21, 31, 40), als es ist Definition nicht (33, 53). Andere Abfragen zeigen dasselbe nur in einer anderen Form. Bist du sicher, dass du immer noch Platten mit 33, 53 in deinen Resluts bekommst? – pawel7318

+0

Ich habe niemanden gesehen, der php 4 seit Jahren benutzt ... es ist stark veraltet und absolut nicht sicher. Außerdem sollte es keine Auswirkungen auf Abfragen haben. Als @paul erwähnt verwenden Sie EXPLAIN vor Ihren Abfragen. Es sollte, naja, erklären, was es tut und welche Indizes es verwendet ... es fehlt wahrscheinlich etwas –

Antwort

2

Hier ist eine Methode, die Aufträge zu erhalten, die Ihre Kriterien erfüllen:

SELECT o.orders_id 
FROM orders o JOIN 
    orders_status_history osh 
    ON o.orders_id = osh.orders_id 
WHERE (o.shipping_module LIKE '%pickup_pickup%' OR 
     o.shipping_module LIKE '%pickup2_pickup2%' 
    ) AND 
     osh.orders_status_id IN (7, 21, 31, 40, 33, 53) 
GROUP BY o.orders_id 
HAVING SUM(osh.orders_status_id IN (33, 53)) = 0; 

Die WHERE wählt nur die Status aus, die Ihnen wichtig sind. Die HAVING stellt sicher, dass Sie nicht die letzten zwei haben.

Wenn Sie die Details der Aufträge oder Auftragszeilen wollen, dann müssen Sie diese Tabellen kommen zurück in.

Verwandte Themen