#ifndef __AccumulateInsert_h_ #define __AccumulateInsert_h_ #include #include /* This unit makes it easy to build up SQL statements that use the extended insert syntax. The MySQL manual suggests that this can improve performance. Early testing showed that this could approximately double the performance. I was inserting alerts into the alerts table and doing it as fast as I could. This was old hardware. I was using INSERT DELAYED, so some data was copied to a buffer, but that buffer was finite, so eventually the program that was sending the data would stall. More recent testing showed a performance boost of 165 times. I'm not certain what the difference was. We are now using InnoDB tables, rather than MyISAM tables. This is the candles_5m table, which has less data per row than the alerts table. This is much faster hardware. In particular this is a RAID 0 (which is the best for write speed) of 2 15k SCSI drives. The original measurements came from an IDE drive, possibly before I got the DMA settings right. These were replace statements, all of which deleted one row and added a new row. (It appears that the speedup is slightly greater when the replace does not have to do the delete.) This test was based on real work that we were doing. It was not a hypothetical test. Some databases would spend hours trying to process our overnight update. The disk would be on continuously. (One CPU spent 100% of it's time in a wait state.) This was devistating to the replication setup as all other changes had to wait for these changes. The exact time seemed to vary from one machine to the next. But the improvement appears to be big in all cases. */ class AccumulateInsert { private: const std::string _common; std::string _accumulated; public: // Store the common part, such as "INSERT IGNORE INTO my_table(field1, // field2)" or "REPLACE INTO mytable". AccumulateInsert(std::string const &common); // Add new data to be inserted, such as "(now(), 3)" void add(std::string const &toInsert); // If Empty is true there is no data to insert. Do no try to call Get // if this is empty. You CAN call get if and only if Empty returns // false. bool empty() const { return _accumulated.empty(); } // If Full is true you should call Get as soon as possible. If Full // is true, that implies that Empty is false. bool full(uint64_t limit = 1048576) const { return _accumulated.size() >= limit; } // This returns a full SQL statement. It also clears the buffer so that // Empty will return true and the next call to Get will not return the // same data. std::string get(); }; #endif