martin weiler: qery in grosser mySql datenbank

halli hallo .. !

ich habe eine md5-hash datenbank mit ~ 10 Mio. einträgen.
wenn ich jetzt eine suche nach einem hash durchführe, dauert dies in etwa ~ 5 sekunden. hätte jemand ideen und/oder vorschläge, wie ich meine tabelle schneller und effizienter abfragen könnte?
ich möchte zb auch mehrere hashes auf einmal auslesen ... das dauert dann bei mir schon ne ganze weile.

meine struktur der tabelle ist:

CREATE TABLE md5 (
  id int(20) NOT NULL auto_increment,
  hash varchar(32) collate latin1_general_ci NOT NULL,
  value varchar(75) collate latin1_general_ci NOT NULL,
  PRIMARY KEY  (id)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;

mein query sieht etwa folgendermassen aus:

$query = mysql_query('select value from md5 where hash = ''.$hash.''');

.. sollte ich lieber ordner erstellen, zb mit den ersten zwei chars des hashes ? und die daten in textfiles lagern ? zb ..

folder: aa / file: bb.txt

darin wären dann alle hashes die etwa so beginnen würden:
  >> aabb****************************

gruss martin

  1. Hi,

    wenn ich jetzt eine suche nach einem hash durchführe, dauert dies in etwa ~ 5 sekunden. hätte jemand ideen und/oder vorschläge, wie ich meine tabelle schneller und effizienter abfragen könnte?

    ja, den Standardvorschlag: Setz einen Index. Beachte dabei, dass pro Abfrage IIRC nur ein Index verwendet wird. Wenn du also nur nach dem hash suchst, solltest du genau dafür auch einen Index anlegen.

    MfG
    Rouven

    --
    -------------------
    ie:| fl:| br:> va:| ls:& fo:) rl:( n4:{ ss:) de:] js:| ch:? mo:} zu:|
    1. hallo,

      wenn ich jetzt eine suche nach einem hash durchführe, dauert dies in etwa ~ 5 sekunden. hätte jemand ideen und/oder vorschläge, wie ich meine tabelle schneller und effizienter abfragen könnte?
      ja, den Standardvorschlag: Setz einen Index. Beachte dabei, dass pro Abfrage IIRC nur ein Index verwendet wird. Wenn du also nur nach dem hash suchst, solltest du genau dafür auch einen Index anlegen.

      das bringt aber auch nur dann einen erfolg, wenn die hash's relativ häufig mehrfach vorkommen. ansonsten braucht man nur mehr speicher, erhöht aber nicht die geschwindigkeit.

      grüße Chris

      1. Hi,

        das bringt aber auch nur dann einen erfolg, wenn die hash's relativ häufig mehrfach vorkommen. ansonsten braucht man nur mehr speicher, erhöht aber nicht die geschwindigkeit.

        wieso, was hat das damit zu tun? Wenn ich einen bspw. einen aufsteigenden Index anlege, kann ich mit einer binären Suche drauf losgehen. Damit lande ich plötzlich bei logarithmischem statt linearem Laufzeitverhalten.
        Ich gebe dir allerdings recht, gerade bei sehr großen Tabellen könnte eine Einfügeoperation recht aufwändig werden...

        MfG
        Rouven

        --
        -------------------
        ie:| fl:| br:> va:| ls:& fo:) rl:( n4:{ ss:) de:] js:| ch:? mo:} zu:|
        1. Hallo Rouven,

          Ich gebe dir allerdings recht, gerade bei sehr großen Tabellen könnte eine Einfügeoperation recht aufwändig werden...

          nicht aufwendiger als bei jeder anderen Tabelle mit einem Index. Bei einem gesunden Verhältnis von Lese- zu Einfügeoperationen (viel mehr Leseoperationen als Einfügeoperationen) macht sich der Index sicherlich bezahlt.

          Freundliche Grüße

          Vinzenz

      2. yo,

        das bringt aber auch nur dann einen erfolg, wenn die hash's relativ häufig mehrfach vorkommen. ansonsten braucht man nur mehr speicher, erhöht aber nicht die geschwindigkeit.

        genau das gegenteil ist der fall, je "unterschiedlicher" (kardinalität) die einträge in der tabelle, desto besser für einen nicht binären index.

        Ilja

    2. Hallo

      ja, den Standardvorschlag: Setz einen Index. Beachte dabei, dass pro Abfrage IIRC nur ein Index verwendet wird. Wenn du also nur nach dem hash suchst, solltest du genau dafür auch einen Index anlegen.

      Martin, damit Du ein Gefühl für den Geschwindigkeitsvorteil bekommst:
      Bei Deinen 10.000.000 Einträgen muss ohne Index Deine komplette Tabelle durchsucht werden, mit Index werden die Einträge mit ca. 21 Operationen gefunden. Du siehst den Unterschied? Nutze EXPLAIN, um Dir Informationen anzusehen, wie MySQL Deine Abfrage abarbeitet.

      Freundliche Grüße

      Vinzenz

      1. vielen dank schon mal für die antworten

        Bei Deinen 10.000.000 Einträgen muss ohne Index Deine komplette Tabelle durchsucht werden, mit Index werden die Einträge mit ca. 21 Operationen gefunden. Du siehst den Unterschied?

        nicht wirklich, ich habe doch mit id einen index ? oder wie ist das gemeint ?

        gruss

        1. hi,

          Bei Deinen 10.000.000 Einträgen muss ohne Index Deine komplette Tabelle durchsucht werden, mit Index werden die Einträge mit ca. 21 Operationen gefunden. Du siehst den Unterschied?

          nicht wirklich, ich habe doch mit id einen index ? oder wie ist das gemeint ?

          Du sollst einen Index auf die Spalte legen, in der du suchen willst - also auf hash.

          Wenn dir das nichts sagt, schlage bitte zum Thema im MySQL-Manual nach.

          gruß,
          wahsaga

          --
          /voodoo.css:
          #GeorgeWBush { position:absolute; bottom:-6ft; }
          1. Wenn dir das nichts sagt, schlage bitte zum Thema im MySQL-Manual nach.

            gruß,
            wahsaga

            doch doch, sagt mir sehr wohl etwas - und hat auch geholfen !

            vielen dank !

      2. yo,

        Bei Deinen 10.000.000 Einträgen muss ohne Index Deine komplette Tabelle durchsucht werden, mit Index werden die Einträge mit ca. 21 Operationen gefunden.

        ganz so einfach ist tuning nun doch nicht. ein index ist ein gutes, aber kein allheilmittel. ein index kann die suche sogar langsamer machen. vieles hängt von der art der daten ab. bei tuning gilt eben die goldene regel, probieren geht über studieren.

        Ilja