MySQL soll im LIFO-Prinzip arbeiten.

Es ist vom Gedankenweg her immer die eine und selbe Anforderung. Ich wollte sie abstrakt halten.
Hier noch ein Beispiel, worauf ich hinaus will:
Code:
Eintraege:
+-------------------------------------+
| id | artikelname | preis | ab | cd  |
+-------------------------------------+
|  1 |        abcd | 10000 |  1 | 65  |
|  2 |        efgh |  2000 | 99 | 25  |
|  3 |        abcd |  1000 | 78 | 22  |
|  4 |        mfgp |   500 | 65 |  8  |
|  5 |        qfgt |  1750 | 12 | 11  |
|  6 |        abcd |   100 | 55 | 12  |
+-------------------------------------+

Suchauftrag:
+------------------------------------------------+
| id | suchename | preismin | preismax | ab | cd |
+------------------------------------------------+
|  1 |      %ab% |        0 |    10001 |  0 |  1 |
|  2 |      %fg% |      100 |      500 |  5 | 20 |
|  3 |      %bc% |     1500 |     1700 | 10 |  5 |
+------------------------------------------------+

Üblicher SQL-Abfrage (mit INDEX auf preis)
SQL:
SELECT * FROM Eintraege AS e, Suchauftrag AS s
WHERE e.artikelname LIKE s.suchename
AND e.preis BETWEEN s.preismin AND s.preismax
AND e.ab > s.ab
AND e.cd > s.cd
GROUP BY e.id  -- Redundanten vermeiden
ORDER BY e.id
LIMIT 10

Diese Abfrage kostet mir jedoch enorm viel Zeit. Deshalb wollte ich es so umstellen, das die 1. Tabelle zuerst einmal gelesen wird (ORDER BY id DESC) und bei entsprechender Kriterien (bezogen auf Tabelle 2) aufgenommen wird.
 
So in etwa:
Code:
Eintraege:                              Suchauftrag:
+--------------------------------------------------------------------------------------+
| id | artikelname | preis | ab | cd  | id | suchename | preismin | preismax | ab | cd |
+--------------------------------------------------------------------------------------+
|  6 |        abcd |   100 | 55 | 12  |  1 |      %ab% |        0 |    10001 |  0 |  1 |
|  6 |        abcd |   100 | 55 | 12  |  3 |      %bc% |     1500 |     1700 | 10 |  5 | -- WEGEN GROUP BY e.id soll diese Tulpe nicht angezeigt werden.   
|  4 |        mfgp |   500 | 65 |  8  |  2 |      %fg% |      100 |      500 |  5 | 20 |
|  3 |        abcd |  1000 | 78 | 22  |  1 |      %ab% |        0 |    10001 |  0 |  1 |
|  1 |        abcd | 10000 |  1 | 65  |  1 |      %ab% |        0 |    10001 |  0 |  1 |
|  1 |        abcd | 10000 |  1 | 65  |  3 |      %bc% |     1500 |     1700 | 10 |  5 | -- WEGEN GROUP BY e.id soll diese Tulpe nicht angezeigt werden.
+--------------------------------------------------------------------------------------+
 
Die folgende Zeile darf eh nicht erscheinen, weil der Preis kleiner als preismin ist
| 6 | abcd | 100 | 55 | 12 | 3 | %bc% | 1500 | 1700 | 10 | 5 | -- WEGEN GROUP BY e.id soll diese Tulpe nicht angezeigt werden.
Auch diese Zeile ist aussehralb des Preisfeldes
| 1 | abcd | 10000 | 1 | 65 | 3 | %bc% | 1500 | 1700 | 10 | 5 | -- WEGEN GROUP BY e.id soll diese Tulpe nicht angezeigt werden.


Und wo sehe ich in deinem Beispiel etwas von der 10er Limite?
In deinem Letzten SQL nimmt er ja die Limit über alles. Aber ich glaube, du willst die ersten 10 pro Suchauftrag. Oder ist das falsch?

Am besten stellst du mal ein Excel-file hoch mit 100 Zeilen deriner Datenbank mit den Testdaten drin, mit denen man auch ein Script entwerfen und Testen kann.
Deine letzten Veröffentlichten Testdaten taugen wenig. Der GROUP-BY-Effekt kann nciht getestet werden. Der LIMI-Effekt auch nicht. Eigentlich nur der JOIN und der macht nicht die Probleme.
 
SQL:
SELECT
   *, '1' AS `inserat_status`
FROM
   (
       SELECT
           suche.`id` AS `sucheID`,
           suche.`radius` AS `sucheRadius`,
           i.`id`,
           i.`typed`,
           i.`inserat_id`,
           i.`linked`,
           i.`name`,
           i.`ez_m`,
           i.`ez_j`,
           i.`km`,
           i.`info`,
           i.`infozusatz`,
           i.`bild`,
           i.`preis`,
           i.`preisval`,
           i.`ort_plz`,
           i.`ort_name`,
           i.`timeed`,
           i.`inserat_time`,
           i.`custom`,
           ROUND(
               ACOS(
                   SIN(RADIANS(suche.`ort_lat`)) * SIN(RADIANS(i.`ort_lat`)) + COS(RADIANS(suche.`ort_lat`)) * COS(RADIANS(i.`ort_lat`)) * COS(
                       RADIANS(i.`ort_lng`) - RADIANS(suche.`ort_lng`)
                   )
               ) * 6371
           ) AS `entfernung`
       FROM
           `inserate` AS `i`,
           `benutzer_suche` AS `suche`
       WHERE
           suche.`userid` = 1
       AND i.`id` <= suche.`maxid`
       AND (
           i.`name` LIKE suche.`name_regexp`
       )
       AND (
           i.`typed` REGEXP suche.`portal`
       )
       AND (
           i.`custom` REGEXP suche.`custom`
       )
       AND i.`preisval` BETWEEN suche.`preisval`
       AND suche.`preisval2`
       AND i.`km` BETWEEN suche.`km`
       AND suche.`km2`
       AND i.`ez_j` BETWEEN suche.`ez_j`
       AND suche.`ez_j2`
       -- LIMIT 1000  SUBQUERY SOLL NICHT ÜBERLAUFEN, JEDOCH FÄLSCHT ES DIE ERGEBNISSE :/
   ) _tmp
WHERE
   `entfernung` <= `sucheRadius`
GROUP BY
   `id`
ORDER BY
   `id` DESC
LIMIT 20 OFFSET 0;

Dies ist mein momentane abfrage.... Im Anhang befinden sich die gewünschten Exel dateien.

(bestand = tabelle -> inserate)
 

Anhänge

  • benutzer_suche.xls
    5,5 KB · Aufrufe: 3
  • bestand.xls
    80 KB · Aufrufe: 7
Zuletzt bearbeitet:
Ich will die ersten 10 Eintrage der gesamten Suchaufträge.
Genau bestand.xls soll die Relation inserate demonstieren.

Ich vermute bei 100 Einträgen in (bestand.xls bzw. Relation inserate) werden die Suchaufträge keine Ergebnisse liefern.
Besser wäre es, wenn ich bei mein suche name_regxp etwas wie "Audi%" stehen hätte, da die Wahrscheinlichkeit höher ist bei 100 Inseraten auf ein Audi zu stoßen.
 
OK; Mehrere Suchaufträge. Alle gleichwertig behandelt. Vom Gesammtreusltat die ersten 10.
SQL:
SELECT DISTINCT
    i.*
FROM
    bestand AS i,
    benutzer_suche AS suche
WHERE
    suche.userid = 1
    -- Mit den vorhandenTestdaten gibt es bei den vorhanden Testdaten keine Treffer, wenn eine derBeiden Bedinungen aktiv ist
    --       AND i.`id` <= suche.`maxid`
    --       AND i.`name` REGEXP suche.name_regexp
    AND i.typed REGEXP suche.portal
    AND i.custom REGEXP suche.custom
    AND i.preisval BETWEEN suche.preisval AND suche.preisval2
    AND i.km BETWEEN suche.km AND suche.km2
    AND i.ez_j BETWEEN suche.ez_j
    AND suche.ez_j2
ORDER BY i.id
LIMIT 10
Code:
| id      | typed          | inserat_id | linked                                                      | name                                                           | ...
| 3518900 | AutoScout24.de | 305836784  | http://ww3.autoscout24.de/classified/305836784              | Mercedes-Benz A 180 BE AMG Line+Navi Vorrüst.+Xenon+PTS+Autom. | ...
| 3518901 | AutoScout24.de | 305836796  | http://ww3.autoscout24.de/classified/305836796              | Opel Meriva 1.4 DRIVE NaviShz Alufelgen+Allwetter              | ...
| 3518902 | mobile.de      | 239433800  | http://suchen.mobile.de/fahrzeuge/details.html?id=239433800 | Mitsubishi SPACE STAR TÜV neu ohne Mängel!!!! Super g...       | ...
| 3518903 | mobile.de      | 239433804  | http://suchen.mobile.de/fahrzeuge/details.html?id=239433804 | Volkswagen VW Passat 3BG 2.8 V6 4motion                        | ...
| 3518904 | mobile.de      | 239433807  | http://suchen.mobile.de/fahrzeuge/details.html?id=239433807 | Volkswagen VW Passat 2.0 TDI Kombi DSG Trendlinie Nav...       | ...
| 3518905 | mobile.de      | 239433805  | http://suchen.mobile.de/fahrzeuge/details.html?id=239433805 | Volkswagen T6 Multivan                                         | ...
| 3518906 | mobile.de      | 239433806  | http://suchen.mobile.de/fahrzeuge/details.html?id=239433806 | Opel Agila 1.2 16 V                                            | ...
| 3518907 | mobile.de      | 239433808  | http://suchen.mobile.de/fahrzeuge/details.html?id=239433808 | Opel Opel Corsa C GSI 1.7 cdti                                 | ...
| 3518909 | mobile.de      | 239433810  | http://suchen.mobile.de/fahrzeuge/details.html?id=239433810 | Volkswagen Fox 1.2 StyleAluNESRCDHU NEU! GAR                   | ...
| 3518910 | mobile.de      | 239433812  | http://suchen.mobile.de/fahrzeuge/details.html?id=239433812 | Seat Seat Arosa 1. Hand mit servolenkung                       | ...
 
Danke sehr für dein Vorschlag.

Die Antwortzeiten bewegen sich immer noch +1min. Abwärts.
Gib's da keine andere Lösung mit der man kurzere Antwortzeiten erzielen kann? Bei 100 Einträgen macht sich die Antwortzeit nicht bemerkbar, jedoch ab +2M Einträgen kann dies ätzend sein.

Mit INDEX's und Partitionen konnte ich die Antwortzeit ebenso nicht reduzieren. Gibt es da eventuell etwas was ich außer Betracht lasse?
 
Lass dir mal mit EXPLAIN ausgeben, ob die Indexe auch verwendet werden

Und versuch mal ein die Daten vorzufiltern und mit einem INNER JOIN zu verknüpfen
Setze noch ein Index auf suche.userid
SQL:
EXPLAIN EXTENDED
SELECT DISTINCT
	i.*
FROM
	bestand AS i
	INNER JOIN (SELECT * FROM benutzer_suche WHERE userid = 1) AS suche
		ON i.typed REGEXP suche.portal
		-- Mit den vorhandenTestdaten gibt es bei den vorhanden Testdaten keine Treffer, wenn eine derBeiden Bedinungen aktiv ist
		--       AND i.`id` <= suche.`maxid`
		--       AND i.`name` REGEXP suche.name_regexp
		AND i.custom REGEXP suche.custom
		AND i.preisval BETWEEN suche.preisval AND suche.preisval2
		AND i.km BETWEEN suche.km AND suche.km2
		AND i.ez_j BETWEEN suche.ez_j AND suche.ez_j2
ORDER BY i.id
LIMIT 10

Das Problem ist, man kann immer nur Ansätze liefern. Es gibt keine Lösung die immer funktioniert.
 

Neue Beiträge

Zurück