DB Tuning

  • Hi

    Ich hab hier ne Anwendung, die ne Liste mit Objekten generiert.
    Diese Liste möchte ich nun in eine Datenbank abspeichern.

    Eigentlich auch kein großes Problem

    Quellcode

    1. for(int i = 0; i < list.size(); i++){
    2. Connection c = cp.getConnection();
    3. String sql = "INSERT INTO bla bla bla";
    4. c.createStatement().execute(sql);
    5. cp.closeConnection(c);
    6. }


    getConnection() und closeConnection() sind Methoden eines ConnectionPools, den ich selber geschrieben habe. Nix besonderes. Gibt bei Anfrage ne Connection zurück und verwendet diese dann wieder (speichern in nem Vektor)

    Das ganze funktioniert ohne Probleme, nur ist es meiner Meinung nach sehr lahm. Die DB zeigt an, dass ca. 10 kb/s geschrieben werden.

    Irgendwelche vorschläge, ob und wie man das ganze noch etwas tunen kann?

    Greeting
    cr4ch
  • ConnectionPool :

    Quellcode

    1. public class ConnectionPool {
    2. Vector<PoolConnection> vPool = new Vector<PoolConnection>();
    3. String strDriver, strURLDatabase;
    4. public ConnectionPool(String strDriver, String strURLDatabase){
    5. this.strDriver = strDriver;
    6. this.strURLDatabase = strURLDatabase;
    7. }
    8. public ConnectionPool(){
    9. this.strDriver = "com.mysql.jdbc.Driver";
    10. this.strURLDatabase = "jdbc:mysql://127.0.0.1:3306/test";
    11. }
    12. public Connection getConnection(){
    13. PoolConnection poolCon;
    14. for (int i = 0; i < vPool.size(); i++) {
    15. if(!vPool.elementAt(i).finUse){
    16. poolCon = vPool.elementAt(i);
    17. poolCon.finUse = true;
    18. return poolCon.con;
    19. }
    20. }
    21. Connection con;
    22. try{
    23. Class.forName(strDriver);
    24. con = DriverManager.getConnection(strURLDatabase);
    25. }
    26. catch(Exception ex){
    27. ex.printStackTrace();
    28. return null;
    29. }
    30. poolCon = new PoolConnection(con, true);
    31. vPool.addElement(poolCon);
    32. return con;
    33. }
    34. public void closeConnection(Connection con){
    35. try{
    36. int c = 0;
    37. while(!vPool.elementAt(c).con.equals(con)){
    38. c++;
    39. }
    40. vPool.elementAt(c).finUse = false;
    41. }
    42. catch(Exception ex){
    43. ex.printStackTrace();
    44. }
    45. }
    46. }
    47. class PoolConnection{
    48. Connection con;
    49. boolean finUse;
    50. public PoolConnection(Connection con, boolean finUse){
    51. this.con = con;
    52. this.finUse = finUse;
    53. }
    54. }
    Alles anzeigen
  • Das Konstrukt

    Quellcode

    1. Vector<PoolConnection> vPool = new Vector<PoolConnection>();

    ist mir von der Syntax her nicht bekannt, aber der Code macht Sinn und scheint auch zu funktionieren.

    Wenn ich raten müßte wo soviel Zeit verbraucht wird, dann würde ich aber auf die Schleifen in getConnection() & closeConnection() tippen.

    Hast du schonmal versucht die Zeit zu messen, die das Erzeugen und Zurückgeben der Connections benötigt?

    ICH IDIOT!

    Warum holst du für jedes Statement eine eigene Connection?

    Quellcode

    1. Connection c = cp.getConnection();
    2. for(int i = 0; i < list.size(); i++){
    3. String sql = "INSERT INTO bla bla bla";
    4. c.createStatement().execute(sql);
    5. }
    6. cp.closeConnection(c);


    Wie lange dauert das denn?
  • "Marcus Gnaß" schrieb:

    Das Konstrukt

    Quellcode

    1. Vector<PoolConnection> vPool = new Vector<PoolConnection>();

    ist mir von der Syntax her nicht bekannt, aber der Code macht Sinn und scheint auch zu funktionieren.

    Das sind Java Generics - das ist schon okay so :)

    Hast du eigentlich eine Web-Anwendung oder eine Standalone-Applikation.
    Wenn es eine Web-Anwendung ist und du Tomcat verwendest, kannst du das automatische Connection-Pooling von Tomcat verwenden - das ist vielleicht noch eine Spur schneller, da er nicht in jedem Request die Verbindung öffnen muss.
  • Moin Moin

    Also ich hab gestern mal den Vorschlag von Marcus ausprobiert, aber das ist auch nicht wirklich schneller (Zumindestens hab ich nicht das gefühl)

    phax
    Es ging allgemein um Datenbanken in Anwendungen. Hab sowohl verwendung für Standalone als auch für eine Web-Anwendung. Bei der benutze ich zur Zeit noch kein Connection-Pooling, werde das aber auf jeden fall noch in Angriff nehmen. Aktuell ist das Objekt selber dafür verantwortlich, sich in die DB zu schreiben.

    ich will wieder in mein Bett !!!
  • Altes Thema neues Problem:
    Kann mir mal wer sagen an welchen Stelle ich bei meinem ConnectionPool ein Speicherleck habe?

    muss ne gewisse menge datensätze in ne db schreiben.
    Bekomme irgendwann ein heap Exception
    Etwas rumgesucht und scheinbar hat ich irgendein Problem mit meinem ConnectionPool. Auch wenn ich noch getConnection und closeConnection mache hab ich nach ca. 30.000 Datensätzen 50 - 80 mb im speicher

    hab das Teil mitlerweile als Singleton realisiert.
    Daher kann auch nur eine Instance vorhanden sein

    Quellcode

    1. public class ConnectionPool {
    2. private final static int MAXCONNECTIONS = 20; // Verbindungen
    3. private final static long ZEITRAUM = 1000l; // 1 Sekunde
    4. private final static int WAIT = 250; // 1/4 Sekunde
    5. private static PropertiesSingleton config = PropertiesSingleton.getInstance();;
    6. private static ConnectionPool connectionPool;
    7. private Vector<PoolConnection> vPool = new Vector<PoolConnection>();
    8. private int anz = 0;
    9. private long start = System.currentTimeMillis();
    10. private long time;
    11. private ConnectionPool(){
    12. }
    13. private ConnectionPool(String configFile){
    14. try {
    15. config = PropertiesSingleton.getInstance(configFile);
    16. } catch (IOException e) {
    17. e.printStackTrace();
    18. config = PropertiesSingleton.getInstance();
    19. }
    20. }
    21. public static ConnectionPool getInstance(){
    22. if(connectionPool == null){
    23. connectionPool = new ConnectionPool();
    24. }
    25. return connectionPool;
    26. }
    27. public static ConnectionPool getInstance(String configFile){
    28. if(connectionPool == null){
    29. connectionPool = new ConnectionPool(configFile);
    30. }
    31. return connectionPool;
    32. }
    33. public Connection getConnection() throws SQLException{
    34. anz++;
    35. time = System.currentTimeMillis() - start;
    36. PoolConnection poolCon;
    37. /*
    38. * Prüft wie viele Connections in einem gewissen Zeitraum hergestellt wurden
    39. * und legt bei bedarf eine Pause ein.
    40. */
    41. if(time > ZEITRAUM && anz < MAXCONNECTIONS){
    42. start = System.currentTimeMillis();
    43. anz = 0;
    44. }
    45. else if(anz > MAXCONNECTIONS && time < ZEITRAUM){
    46. anz = 0;
    47. try {
    48. Thread.sleep(WAIT);
    49. } catch (InterruptedException e) {
    50. e.printStackTrace();
    51. }
    52. start = System.currentTimeMillis();
    53. }
    54. /*
    55. * ENDE
    56. */
    57. for (int i = 0; i < vPool.size(); i++) {
    58. if(!vPool.elementAt(i).finUse){
    59. poolCon = vPool.elementAt(i);
    60. poolCon.finUse = true;
    61. return poolCon.con;
    62. }
    63. }
    64. Connection con;
    65. try{
    66. Class.forName(config.getProperty("db.db"));
    67. }
    68. catch(ClassNotFoundException ex){
    69. throw new SQLException("Could not load DB Driver!");
    70. }
    71. con = DriverManager.getConnection(config.getProperty("db.driver"),
    72. config.getProperty("db.user"), config.getProperty("db.password"));
    73. poolCon = new PoolConnection(con, true);
    74. vPool.addElement(poolCon);
    75. return con;
    76. }
    77. public void closeConnection(Connection con){
    78. try{
    79. int c = 0;
    80. while(!vPool.elementAt(c).con.equals(con)){
    81. c++;
    82. }
    83. vPool.elementAt(c).finUse = false;
    84. }
    85. catch(Exception ex){
    86. ex.printStackTrace();
    87. }
    88. }
    89. }
    90. class PoolConnection{
    91. Connection con;
    92. boolean finUse;
    93. public PoolConnection(Connection con, boolean finUse){
    94. this.con = con;
    95. this.finUse = finUse;
    96. }
    97. }
    Alles anzeigen

    mfg
    Ubuntu Edgy * Kernel 2.6.17 * Gnome 2.16 * Beryl
    2 x Athlon MP 1900 * MSI K7D Master-L * 1024 MB ECC DDR333
    Hercules 9800XT 256 MB Ram * 1x 250 GB IDE
    Wasserkühlung