MySQL Verbindung nach außen sehr langsam

PaP

Mitglied
Hallo zusammen,

ich sitze zurzeit an einem kleinen Tool zur MySQL Datenbank Verwaltung. Ich habe mich bis jetzt noch nicht sonderlich viel mit Java in Verbindung mit MySQL auseinandergesetzt aber bis jetzt habe ich eigentlich das umsetzen können, was ich wollte. Das Programm funktioniert wunderbar - abgesehen von einigen kleinen Bugs - wenn ich mich auf meinen lokalen MySQL Server verbinde.

Wenn ich mich jedoch extern auf einen MySQL Server, mit den gleichen Datenbanken verbinden möchte, braucht er ca 3 Minuten, um sich zu Verbinden und um "SHOW DATABASES" auszuführen.

An was kann das liegen? Ich habe euch hier im Topic meine Hauptklasse beigelegt. Wenn es gewünscht ist stelle ich noch die anderen Klassen zur Verfügung.


Java:
import javax.swing.*;
import javax.swing.table.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;

public class PatDatabaseManager extends JFrame
{
    
    JButton b1, b2;
    JPanel panel;
    LoadTable loadtable;
    JComboBox showDatabases, showTables;
    JTable tab;
    String[] databases;
    String table = "TABLES";
    static String[][] data;
    static int cols;
    static int rows;
    static String[] field;
    String database = "information_schema";
    
    JMenuBar mb;
    JMenu datei, bearbeiten, hilfe;
    JMenuItem beenden, about;
    
    public PatDatabaseManager()
    {
        setSize(800,600);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(null);
        
        mb = new JMenuBar();
        mb.setBounds(1, 1, getWidth(), 20);
        add(mb);
        
        datei = new JMenu("Datei");
        mb.add(datei);
        
        bearbeiten = new JMenu("Bearbeiten");
        mb.add(bearbeiten);
        
        hilfe = new JMenu("Hilfe");
        mb.add(hilfe);
        
        about = new JMenuItem("About");
        hilfe.add(about);
        about.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                JOptionPane.showConfirmDialog(null, "Database-Manager for MySQL v0.3 by Patrick Farnkopf", "About", JOptionPane.CLOSED_OPTION);
            }
        });
        
        beenden = new JMenuItem("Beenden");
        datei.add(beenden);
        beenden.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                dispose();
            }
        });
        databases = loadtable.GetDatabases();
        showDatabases = new JComboBox();
        showTables = new JComboBox();
        
        setTitle("Database-Manager for MySQL");
        
        for (int itr = 0; itr < databases.length; itr++)
        {
            showDatabases.addItem(databases[itr]);
        }
        
        b2 = new JButton("Export to CSV");
        b2.setBounds(10, 150, 150, 25);
        add(b2);
        
        b2.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                try
                {
                    JFileChooser fc = new JFileChooser();
                    fc.showSaveDialog(null);
                    PrintStream ps = new PrintStream(fc.getSelectedFile());
                    
                    for (int itr = 0; itr < rows; itr++)
                    {
                        for (int iitr = 0; iitr < cols; iitr++)
                        {
                            if (data[iitr][itr] == null)
                                ps.print("0,");
                            else
                                ps.print(data[iitr][itr]+",");
                        }
                        ps.println();
                    }
                    
                    JOptionPane.showConfirmDialog(null, "Export erfolgreich", "SQL2CSV", JOptionPane.CLOSED_OPTION);
                    
                } catch (Exception x){}
            }
        });
        
        showDatabases.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                showTables.removeAllItems();
                
                String cbDB = showDatabases.getItemAt(showDatabases.getSelectedIndex()).toString();
                database = cbDB;
                System.out.println(cbDB);
                String[] tables = loadtable.GetTables(cbDB);
                
                for (int itr = 0; itr < tables.length; itr++)
                {
                    System.out.println(tables[itr]);
                    showTables.addItem(tables[itr]);
                }
            }
        });
        
        showTables.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                if (showTables.getItemCount() != 0)
                        table = showTables.getItemAt(showTables.getSelectedIndex()).toString();
                
                data = new String[cols][rows];
                field = loadtable.GetFields(table, database);
                cols = loadtable.GetFields(table, database).length;
                rows = loadtable.GetRowCount(table, database);
                data = new String[cols][rows];
                
                for (int colItr = 0; colItr < cols; colItr++)
                {
                    String[] temp = loadtable.GetData(table, database, colItr);

                    for (int rowItr = 0; rowItr < rows; rowItr++)
                    {
                        data[colItr][rowItr] = temp[rowItr];
                        System.out.println(data[colItr][rowItr]);
                    }
                    
                }
                ((AbstractTableModel)tab.getModel()).fireTableStructureChanged();
                ((AbstractTableModel)tab.getModel()).fireTableDataChanged();
            }
        });
        
        showDatabases.setBounds(10, 30, 150, 20);
        add(showDatabases);
        
        showTables.setBounds(10, 60, 150, 20);
        add(showTables);
        
        b1 = new JButton("Refresh");
        b1.setBounds(10, 100, 150, 25);
        add(b1);
        
        b1.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {                
                ((AbstractTableModel)tab.getModel()).fireTableStructureChanged();
                ((AbstractTableModel)tab.getModel()).fireTableDataChanged();
            }
        });
        
        
        loadtable = new LoadTable();
        panel = new JPanel();
        panel.setBounds(60, 25, 800, 800);
        
        field = loadtable.GetFields(table, database);
        cols = loadtable.GetFields(table, database).length;
        rows = loadtable.GetRowCount(table, database);
        data = new String[cols][rows];
        
        for (int colItr = 0; colItr < cols; colItr++)
        {
            String[] temp = loadtable.GetData(table, database, colItr);
            
            for (int rowItr = 0; rowItr < rows; rowItr++)
            {
                data[colItr][rowItr] = temp[rowItr];
            }
        }
        
        tab = new JTable(new AbstractTableModel()
        {
            public int getColumnCount()
            {
                return GetColumns();
            }
            
            public int getRowCount()
            {
                return GetRows();
            }
            
            public boolean isCellEditable(int z, int s)
            {
                return true;
            }
            
            public Object getValueAt(int z, int s)
            {
                return GetData()[s][z];
            }
            
            public void setValueAt(Object v, int z, int s)
            {
                
            }
            
            public String getColumnName(int index)
            {
                return GetField()[index];
            }
        });
        
        tab.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        
        JScrollPane sp = new JScrollPane(tab);
        sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        sp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        panel.add(sp);
        add(panel);
        setVisible(true);
    }
    
    static String[][] GetData()
    {
        return data;
    }
    
    static String[] GetField()
    {
        return field;
    }
    
    static int GetRows()
    {
        return rows;
    }
    
    static int GetColumns()
    {
        return cols;
    }
    
    public static void main(String[] args) 
    {
        new LoginWindow();
    }
}
 
S

SlaterB

Gast
du postest nur deineb GUI-Code, zu dem man den guten Hinweis geben kann, dass er völlig ohne Belang hier ist ;)
erstelle eine main, erzeuge LoadTable, was immer das ist und rufe in etwa EINER Zeile
> loadtable.GetFields(table, database);
auf, entweder ist das schnell (dann könnte tatsächlich noch die GUI Probleme bereiten, ach ne, lokal gehts ja, damit dürfte GUI als Ursache ziemlich sicher wegfallen)
oder langsam, wie sieht es aus?

falls LoadTable deine Klasse ist kannst du die auch noch posten, aber viel Hoffnung habe ich allerdings nicht,
hast du ein anderes Tool um die DB zu testen zum Vergleich?
 

PaP

Mitglied
Also hier ist meine LoadTable Klasse. Der Name ist etwas ungünstig gewählt, weil ich über diese auch die Datenbanken aufliste.

Java:
import java.sql.*;
import java.util.*;

public class LoadTable 
{
    public LoadTable(){}
    
    static int GetRowCount(String table, String database)
    {
        Database db = new Database(database);
        
        try
        {
            ResultSet result = db.QueryResult("SELECT * FROM "+table);
            result.first();
            
            int amount = 0;
            do amount++; while (result.next());
            return amount;
        } catch (Exception e) { return 1; }
    }
    
    static String[] GetFields(String table, String database)
    {
        Database db = new Database(database);
        
        try
        {
            ResultSet result = db.QueryResult("SHOW COLUMNS FROM "+table);
            result.first();
            int count = 0;
            
            do
            {
                count++;
            } while (result.next());
            
            result.first();
            
            String[] name = new String[count];
            
            for (int itr = 0; itr < count; itr++)
            {
                name[itr] = result.getString("Field");
                result.next();
            }
            
            return name;
            
        } 
        catch (Exception e) 
        {
            String[] error = {""};
            return error;
        }
    }
    
    static String[] GetTables(String database)
    {
        Database db = new Database(database);
        
        try
        {
            ResultSet result = db.QueryResult("SHOW TABLES");
            result.first();
            int count = 0;
            
            do
            {
                count++;
            } while (result.next());
            
            result.first();
            
            String[] name = new String[count];
            
            for (int itr = 0; itr < count; itr++)
            {
                name[itr] = result.getString("Tables_in_"+database);
                result.next();
            }
            
            return name;
            
        } 
        catch (Exception e) 
        {
            String[] error = {""};
            return error;
        }
    }
    
    static String[] GetDatabases()
    {
        Database db = new Database("mysql");
        
        try
        {
            ResultSet result = db.QueryResult("SHOW DATABASES");
            result.first();
            int count = 0;
            
            do
            {
                count++;
            } while (result.next());
            
            result.first();
            
            String[] name = new String[count];
            
            for (int itr = 0; itr < count; itr++)
            {
                name[itr] = result.getString("Database");
                result.next();
            }
            
            return name;
            
        } 
        catch (Exception e) 
        {
            String[] error = {""};
            return error;
        }
    }
    
    static String[] GetData(String table, String database,int col)
    {
        Database db = new Database(database);
        String field[] = GetFields(table, database);
        String[] data = new String[GetRowCount(table, database)];
        
        try
        {
            ResultSet result = db.QueryResult("SELECT "+field[col]+" FROM "+table);
            result.first();
            System.out.println(field[col]+""+table);
            int itr = 0;
            do
            {
                data[itr] = result.getString(field[col]);
                itr++;
            } while (result.next());
            return data;
        } catch (Exception e){System.out.println(e);}
        
        return data;
    }
    
/*    static String GetData(String table, int col, int row)
    {
        Database db = new Database();
        String field[] = GetFields(table);
        String data = "";
        try
        {
            ResultSet result = db.QueryResult("SELECT "+field[col]+" FROM "+table);
            result.first();
            System.out.println(row);
            for (int itr = 0; itr <= row; itr++)
            {
                System.out.println("ITR: "+itr);
                if (itr == row)
                    data = result.getString(field[col]);
                result.next();
            }
            
        }
        catch(Exception e){}
        
        return data;
    }*/
}


Ich werde morgen mal ein kleines Programm schreiben, welches mir lediglich einen Query auf einer DB ausführt und werde dann mal schauen, ob das schnell geht. Jetzt muss ich allerdings erstmal schlafen. Muss morgen früh zur Arbeit :(


EDIT#1: Ich habe mich bereits mit HeidiSQL und Navicat zu diesem MySQL Server verbunden und damit geht es ohne Probleme
 
Zuletzt bearbeitet:
J

JohannisderKaeufer

Gast
Die Klasse Database dazu wäre auch nicht schlecht.

Aber zurück zum Thema.
Die Klasse LoadTable ist (hier stellt sich mir die Frage wie ich es am freundlichsten Ausdrücke) in weiten Teilen unterirdisch schlecht implementiert.

Das ist auch der Grund für die Performanceunterschiede.

Grundsätzliches:
Alles was über das Netzwerk geht ist 10 - 100 Mal langsamer als lokale Zugriffe.

1. Beispiel für die schlechte Implementierung

Code:
getRowCount(...){
  db.QueryResult("SELECT * FROM "+table);
  int amount = 0;
  do amount++; while (result.next());
  return amount;
}

Damit wird jeder Datensatz in der Tabelle über das Netzwerk übertragen. Stehen in der Tabelle 100 MB an Daten, braucht die Methode bei einer 1 Mbit Verbindung 800 Sekunden.

Eine Abfrage
Code:
"Select count(*) from "+table
leistet das gleiche muß aber nur, komm lass es 10 Kilobyte sein übertragen. Das läuft deutlich unter einer Sekunde.
Das Zählen der Datensätze wird dabei auf dem Datenbankrechner gemacht, der das auch ganz gut und ganz schnell kann und das ausserdem lieber macht, als alle Datensätze zu übertragen und sein eingenen Netzwerkanschluß auszulasten.


Zweites Beispiel:
getFields()
Hier wird zweimal über das Resultset iteriert, das erste mal um eine Array-Größe zu bestimmen.
Das zweite mal um das Array zu füllen.
Java:
int anzahlSpalten = result.getMetaData.getColumnCount();
liefert das selbe.

getDatabases und getTables laufen nach selbem Schema ab.

Drittes Beispiel:
getData überträgt die Komplette Tabelle einer Datenbank.

Dies ist unüblich für typische DB-Programme, da hierbei wiederum Große Datenmengen bewegt werden müssen.

In der Regel wird hier so vorgegangen, daß nur ein bestimmter Ausschnitt geladen wird. Eben der Ausschnitt der Momentan auch zur Anzeige gebracht werden soll.
Dabei gibt man der DB-Anfrage noch zusätzliche Parameter mit in denen steht dass nur Datensatz 0-100 übermittelt werden soll.

Möchte man weitere Daten anzeigen, dann macht man eine neue Abfrage und gibt als Parameter 101-200 an.

Lokal mag das einem garnicht so Auffallen, außer die DB ist extrem Groß. Wenn das ganze aber übers Netzwerk läuft, dann Prosit und Gute Nacht.
 
S

SlaterB

Gast
Das ist auch der Grund für die Performanceunterschiede.
[..]
Lokal mag das einem garnicht so Auffallen, außer die DB ist extrem Groß. Wenn das ganze aber übers Netzwerk läuft, dann Prosit und Gute Nacht.
wer hat schon zig Mb in einer Tabelle und testet (nur) genau damit?
denkbar ist manches, allzu wahrscheinlich halte ich das aber nicht und zu
braucht er ca 3 Minuten, um sich zu Verbinden und um "SHOW DATABASES" auszuführen.
passt es dann gar nicht mehr
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Thallius MySQL jdbc schließt Verbindung nach vielen Request von selber Datenbankprogrammierung 8
A Nach Export mysql Verbindung zur Datenbank nicht möglich, was tun? Datenbankprogrammierung 7
I Nach export zur .jar keine verbindung mehr Datenbankprogrammierung 7
M Datenbankverbindung bricht nach ca. 12 Stunden Verbindung ab Datenbankprogrammierung 3
TheSkyRider MySQL Datenbankzuordnung in Verbindung mit Java Datenbankprogrammierung 7
raptorrs Plötzlich keine Verbindung zur Datenbank mehr möglich Datenbankprogrammierung 14
OnDemand SSL Verbindung zu externer DB Datenbankprogrammierung 5
C MySQL Remote Verbindung zu MariaDB Datenbankprogrammierung 11
M SQL , CSV Verbindung : Zu Umfangreicher Code durch Unwissenheit Datenbankprogrammierung 21
P Verbindung zu einer Access Datenbank per Eclipse oder Intellij Datenbankprogrammierung 0
Z Beim schließen des Programms die verbindung zur DB beenden. Datenbankprogrammierung 4
Husamoli345 JSF-JDBC Verbindung Crud Datenbankprogrammierung 15
V keine Verbindung möglich (Access-DB) Datenbankprogrammierung 3
H MySQL Verbindung Datenbank und Eclipse (Java) Datenbankprogrammierung 5
M Oracle SQLException: Verbindung getrennt Datenbankprogrammierung 2
S Verbindung von einer Excel Datei zu Java Datenbankprogrammierung 2
C Verbindung mit SQLExpress Datenbankprogrammierung 9
S E(fx)clipse Verbindung zu MS SQL Express aufbauen Datenbankprogrammierung 7
M H2 Verbindung zur Datenbank komplett schließen Datenbankprogrammierung 11
F MySQL Verbindung zum SQL-Server Datenbankprogrammierung 27
H MySQL MySQL - Keine Verbindung zur Datenbank?! Datenbankprogrammierung 4
G MySQL Problem mit MySQL verbindung Datenbankprogrammierung 8
C datenbank verbindung config Datenbankprogrammierung 23
I MariaDB-Verbindung in JAVA Datenbankprogrammierung 11
J Verbindung aufbauen Datenbankprogrammierung 7
S DB2 Express C - keine Verbindung zur Datenbank Datenbankprogrammierung 2
I Es kann keine Verbindung zum Server aufgebaut werden Datenbankprogrammierung 12
Thallius MySQL Merkwürdiges JDBC Verhalten bei VPN Verbindung. Datenbankprogrammierung 7
P MySQL-Verbindung in anderer Klasse nutzen Datenbankprogrammierung 2
W Keine ODBC-Verbindung zur MSAccess-Datenbank Datenbankprogrammierung 2
S Auslagern der Datenbank Verbindung Datenbankprogrammierung 2
M Verbindung von Java Programm zur Acccess Datenbank (mdb-Datei) Datenbankprogrammierung 0
D NullPointerException bei DB Verbindung Datenbankprogrammierung 6
AssELAss Verbindung i5 Series 7.1 / 7.2 (DB2) mit Oracle SQL Developer Datenbankprogrammierung 3
J Verbindung zu Derby Datenbank funktioniert nicht Datenbankprogrammierung 14
M MySQL Verbindung zum Server aufbauen ohne DB ansprechen Datenbankprogrammierung 2
D Java MS Access Verbindung Datenbankprogrammierung 10
X MySQL DB-verbindung ohne JDBC/ODBC Datenbankprogrammierung 1
J Keine Verbindung zu MSSQL DB mit JDBC Datenbankprogrammierung 3
A Verbindung mit Access 2007 Datenbank herstellen Datenbankprogrammierung 1
I Datenbank Verbindung geht nicht Datenbankprogrammierung 2
N MySQL com.microsoft.sqlserver.jdbc.SQLServerException: Die Verbindung wurde geschlossen. Datenbankprogrammierung 1
1 MySQL Verbindung mit localhost als IP funktioniert, aber mit normaler IP nicht Datenbankprogrammierung 2
Helgon H2 Verbindung öffnen/schließen - Dauer, wann, wie lange? Datenbankprogrammierung 2
J Verbindung zu Access Datenbank Datenbankprogrammierung 15
J Verbindung zu Datenbank herstellen Datenbankprogrammierung 26
P JDBC Verbindung zur DB klappt nicht Datenbankprogrammierung 6
J Java - JDBC Verbindung zur Datenbank nicht möglich Datenbankprogrammierung 10
T MySQL Sichere Verbindung Datenbankprogrammierung 6
T MySQL Kann Verbindung zur MySQL Datenbank nicht herstellen. Datenbankprogrammierung 4
S Google Web Toolkit LDAP - Verbindung Datenbankprogrammierung 2
pg1337 Verbindung mit postgres - eclipse Datenbankprogrammierung 4
M Verbindung mit MSSQL hängt! Datenbankprogrammierung 2
cover1012 Derby/JavaDB Verbindung mit FTP-Server Datenbankprogrammierung 13
T NullPointerException bei Verbindung zur Datenbank Datenbankprogrammierung 4
J DB2 Verbindung zu AS400 Datenbankprogrammierung 6
F PostgreSQL JPA und Hibernate - Verbindung zur DB Datenbankprogrammierung 7
J MySQL Verbindung über JDBC scheitert immer Datenbankprogrammierung 2
M MySQL getConnection - Verbindung Problem Datenbankprogrammierung 2
T mdb Verbindung ohne Registrierung der Datenquelle im OS Datenbankprogrammierung 14
K MySQL Verbindung funktioniert in Netbeans aber .jar funktioniert nicht Datenbankprogrammierung 5
jeppi MySQL Design-Problem: DB-Verbindung herstellen und halten - JdbcRowSet / Idle-Timeout? Datenbankprogrammierung 9
S Hibernate in Verbindung mit Hsql Datenbankprogrammierung 2
D Oracle Verbindung mit Java zu Datenbank Datenbankprogrammierung 8
F MSSQL-Server Verbindung Datenbankprogrammierung 5
E Hibernate Problem bei bidirektionaler 1:n Verbindung Datenbankprogrammierung 2
DStrohma MS SQL Server 2005 + Java: Immer nur eine aktive Verbindung erlaubt? Datenbankprogrammierung 5
G MySQL Tables 1:1 verbindung Datenbankprogrammierung 14
B JDBC Verbindung mit Postgresql Datenbankprogrammierung 13
U MSSQL Verbindung steht, aber meckert beim Statement Datenbankprogrammierung 2
G JDBC-Verbindung: User wechseln Datenbankprogrammierung 2
F Kann keine Verbindung mit HSQLDB aufbauen Datenbankprogrammierung 2
N Trennt sich die Verbindung zur DB (MySQL) automatisch? Datenbankprogrammierung 3
X JDBC Verbindung in einer Funktion Datenbankprogrammierung 9
O HSQLDB Verbindung schlägt fehl Datenbankprogrammierung 3
C DB2/AS400 Verbindung Datenbankprogrammierung 2
T Form, Verbindung Feld -> DB Datenbankprogrammierung 3
J Verbindung zur Datenbank schlägt fehl... Datenbankprogrammierung 2
C keine Verbindung zur MS-SQL-Datenbank mehr Datenbankprogrammierung 4
Y Keine verbindung mit der Datenbank Datenbankprogrammierung 2
G verbindung 2er Tabellen Datenbankprogrammierung 3
G persistence.xml für MySQL - Verbindung Datenbankprogrammierung 6
C Keine Verbindung Datenbankprogrammierung 12
G 2 Tabellen in einer 1:n Verbindung Datenbankprogrammierung 2
G Verbindung mit Eclipse auf Datenbank einrichten Datenbankprogrammierung 3
M Verbindung zu Oracle DB Datenbankprogrammierung 4
U *.mdb Datenbank Verbindung mit Pfadangabe Datenbankprogrammierung 3
sparrow Objekt mit lazy-verbindung komplettieren Datenbankprogrammierung 13
M jbcd : odbc Verbindung zu Accessdatei (*.mdb) Datenbankprogrammierung 9
S Fehler bei DB Verbindung Access Datenbankprogrammierung 6
M DB-Verbindung zu DB in Projektordner möglich? Datenbankprogrammierung 17
G jdbc grundlegende verbindung zu sql server geht nicht Datenbankprogrammierung 9
M Passwortvergabe bei Verbindung zwischen jdbc und mysqlServer Datenbankprogrammierung 2
M Verbindung überprüfen und bei Bedarf neu aufbauen Datenbankprogrammierung 3
M Fehler bei der Verbindung zu einer MSSQL/Express Datenbank! Datenbankprogrammierung 17
B fehlerhafte PostgreSQL-Verbindung Datenbankprogrammierung 4
C Keine Verbindung zu HSQLDB möglich Datenbankprogrammierung 22
S PostgreSQL Verbindung kommt nicht zu stande Datenbankprogrammierung 3
B MySQL-Verbindung ausschließlich zu localhost möglich Datenbankprogrammierung 7
P Verbindung zu einer Datenbank Datenbankprogrammierung 6

Ähnliche Java Themen

Neue Themen


Oben