15. Smart queries
UPDATE developers SET active_seconds = active_seconds + ...
INSERT INTO hourly_usage (...) VALUES (...) ON DUPLICATE KEY UPDATE
active_seconds = active_seconds + ..., idle_seconds = idle_seconds + ...
Allows for concurrency
16. Aim for a Small Rowsize
choose a correct datatype
pick the right indexes
sometimes `id` shouldn’t be the PK
17. composite_primary_keys
Allows efficient PK
class HourlyUsage < ActiveRecord::Base
set_primary_keys :user_id, :software_id, :used_at
...
end
Original implementation by Dr Nic
Maintained by Darrin Holst
http://github.com/drnic/composite_primary_keys
18. Archive old data
that’s not frequently used
SELECT ... FROM hourly_usage WHERE used_at < '...' INTO OUTFILE '/path/to/file'
LOAD DATA LOCAL INFILE '/path/to/file' REPLACE INTO TABLE hourly_usage_storage
avoids long locks
19. Alternative solution
Partitioning
CREATE TABLE hourly_usage_storage ( ... )
PARTITION BY RANGE (software_id) (
PARTITION p0 VALUES LESS THAN (...),
PARTITION p1 VALUES LESS THAN (...),
PARTITION p2 VALUES LESS THAN (...),
PARTITION p3 VALUES LESS THAN (...),
....
PARTITION pn VALUES LESS THAN MAXVALUE
);
Makes ‘WHERE software_id = ...’ very fast
Didn’t work for us
20. Other Techologies
Rails 2.3
Apache
Passenger
REE 1.8.7
MySQL 5.0
Memcached
Sphinx
Amazon EC2