Mac-Adresse als Hexadezimalzahl in MySQLdb speichern

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
Dittrich
User
Beiträge: 21
Registriert: Mittwoch 26. Juni 2013, 08:50

Wenn ich nun Join durch Left Join ersetze

Code: Alles auswählen

 LEFT JOIN mac AS m USE INDEX (mac) ON m.mac=a.mac
explodiert die Laufzeit wieder... hab nach 5 min abgebrochen.
Laut Explain erhalte ich bei Join:

Code: Alles auswählen

id,select_type,table,type,possible_keys,key,key_len,ref,rows,Extra
1,SIMPLE,a,ref,"id,mac",mac,57,func,2,"Using where"
1,SIMPLE,b,ref,id,id,68,"lokalisierung.a.id,lokalisierung.a.einwahlid",2,"Using where"
1,SIMPLE,m,ALL,NULL,NULL,NULL,NULL,17209,"Using temporary"
und bei Left Join:

Code: Alles auswählen

id,select_type,table,type,possible_keys,key,key_len,ref,rows,Extra
1,SIMPLE,a,ALL,id,NULL,NULL,NULL,7702,"Using temporary"
1,SIMPLE,b,ref,id,id,68,"lokalisierung.a.id,lokalisierung.a.einwahlid",2,"Using where"
1,SIMPLE,m,ALL,NULL,NULL,NULL,NULL,17209,
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

Ich würde dennoch das meiste in reinem Python erledigen und nur das füllen der Zieltabelle SQL erledigen lassen:

Code: Alles auswählen

#!/usr/bin/env python
import csv
import os
from itertools import chain
import MySQLdb


def read_into_dict(filename, key_cols=2, delimiter=';'):
    with open(filename) as data_file:
        reader = csv.reader(data_file, delimiter=delimiter)
        return dict((tuple(row[:key_cols]),row[key_cols:]) for row in reader)


def join_dicts(*dicts):
    all_keys = set(itertools.chain(*dicts))
    for key in all_keys:
        yield (key,) + tuple(d[key] for d in dicts)


def main():
    connection = MySQLdb.connect('**********', '**********', '', '**********')
    base_path = 'C:/Dokumente und Einstellungen/***********/Desktop'

    get_pppoe_all = read_into_dict(os.path.join(base_path, 'get_pppoe_all.txt'))
    get_pppoe_detail = read_into_dict(os.path.join(base_path, 'get_pppoe_detail.txt'))
    
    cursor = connection.cursor()
    cursor.executemany(
        """INSERT INTO vergleich
        SELECT %s, %s, %s as a_mac, %s, %s, m.mac_id
        FROM mac AS m WHERE m.mac=a_mac""",
        (a_id, a_einwahlid, a_mac, d_vlan, d_id
         for (a_id, a_einwahlid), (a_mac,), (d_vlan, d_id) in join_dicts(get_pppoe_all, get_pppoe_detail))
    )
    connection.commit()
                       
if __name__ == '__main__':
    main()
Natürlich muß auf mac in der Tabelle mac ein Index existieren, obwohl hier die Zeit nur linear mit der Anzahl der Einträge in mac steigen dürfte.
Antworten