Improving Database Performance? 95
An anonymous reader asks: "An acquaintance of mine runs a fair sized web community. Having nearly 280,000 users in a single MySQL database with about 12 mirrors accessing it, performance has become an big issue. I was wondering what practical methods could be used to lessen the load and decrease user query times. Funds are limited, so he'd rather not pay for a commercial database system at this time."
Memcached (Score:5, Informative)
Re:Memcached (Score:4, Insightful)
Re:Memcached (Score:2)
After that, if it's still slow, add still more RAM.
Seriously, disk access is hideously slow. And disk seeks are much, much slower than that. RAM for the entire user database will be a couple hundred bucks. And if other things on that machine are eating up the RAM, then move the user database to its own machine as a read-only partial clone.
Re:Memcached (Score:2, Interesting)
For many "real" databases, there is most definitely a big IO performance issue, regardless of the amount of RAM in the system. The main reason is the requirement that data be in stable storage after a commit succeeeds in order to comply with ACID semantics (though being MySQL, it wouldn't surprise me if this requiement didn't bother him).
If the database is read-only (and being MySQL, that wouldn't surprise me), then sure, adding more RAM
Re:Memcached (Score:1)
Oh, agreed. We were talking about a user database, which usually has a really heavy read bias. If you're bottlenecking on writes, then a battery-backed write cache can indeed help, possibly quite a bit.
Re:Memcached (Score:2)
does this require a complete rewrite of existing code ?
if so, is there something that will cache transparently so that a code rewrite is not necessary ? thanks !
Re:Memcached (Score:2)
something where I never touch the code, but want improved performance
Re:Memcached (Score:4, Informative)
Pretty much, yes.
Here's an introduction to memcached I wrote [debian-adm...ration.org] which might explain it for you.
In short you modify all the parts of your code that fetch from the database to first check from the memory cache - and when storing invalidate the cache. In general most sites read data more than they write it so most of your accesses come from the cache - thus reducing the load upon your DB.
If you don't want to modify your code you could look at optimizing the setup of the database server, moving it, setting up replication, etc.
Still without more details it is hard to know what to suggest.
Re:Memcached (Score:2)
Re:Memcached (Score:2)
Re:Memcached (Score:1, Informative)
Because memcache doesn't know (or care) how or where the data really comes from.
Re:Memcached (Score:2)
Re:Memcached (Score:1)
If it doesn't, it sucks.
Re:Memcached (Score:2)
Cacheing sounds like your problem (Score:2)
But if you have lots of database updates going ahead, locking and huge index searching, you might want to look at your slowest most costly queries (sometimes they can be stupid little footer fillers) and reduce those queries. Check what is slow, and see how you can work around it, add a new index, or cut the fat.
But seriously, if your 'performance hit' is pulling static stories out of a database, then how come you haven't looked at cacheing?
Postgre-SQL (Score:1)
Re:Postgre-SQL (Score:2, Informative)
Postgresql scales better than Mysql under heavy concurrent read/write conditions. If that is the access pattern for the OP, then I said yes - look into switching to Postgresql.
Re:Postgre-SQL (Score:3, Funny)
Dilbert (thinking):Does he know what he's talking about, or did he read it in a trade magazine ad?
Dilbert (speaking):What color would you like that database?
PHB: I think mauve has the most RAM. -
Re:Postgre-SQL (Score:2)
Mauve Database [flickr.com]
Re:Postgre-SQL (Score:1)
Re:Postgre-SQL (Score:3, Informative)
If the queries are indeed read-mostly, it might be worth benchmarking it against an LDAP server. LDAP servers are built specifically for serving user data, which is usually greater than 99% read. It's been a while since I did benchmarks, but at the time they could beat the pants of of general-purpo
More importantly (Score:5, Informative)
So, for example, if you want to insert a string that is too big for the field, MySQL will gladly suck it up with nary a peep (meanwhile, your data is trashed: truncate hell), whereas Postgre (and other non-toy RDBMSs) will refuse to insert the record.
Wikipedia has a nice comparison [wikipedia.org].
Re:More importantly (Score:2)
Re: (Score:1)
Re:Postgre-SQL (Score:1)
Re:Postgre-SQL (Score:1)
It Depends (Score:5, Insightful)
Re:It Depends (Score:2)
MySQL replication. (Score:5, Informative)
Works like a champ.
Set up multiple read slaves to carry the bulk of your read traffic, especially for your mirrors. Considering MyISAM's native table locking behavior, this should reduce your master db load quite a bit, even just moving your mirror read-load to a slave replicant.
Also, query caching is a beautiful thing.
Re:MySQL replication. (Score:2, Funny)
Re:MySQL replication. (Score:2)
Correct me if I'm wrong, but IIRC from my database design classes in college, isn't table-locking a horribly BAD thing to do? Row-locking is much better, since it allows other items in the table to be accessed and updated while this record is altered.
It depends on how the queries work. (Score:2)
If you do a lot of Writing to the database, you _may_ want to do batch updating. Or buy/build a raid (I still recommend SCSI )
Finally; Databases are easy to use, but hard to master. There are reasons why people get paid hundreds of dollars an hour to fix peoples database problems.
Re:It depends on how the queries work. (Score:1)
Adding keys to your tables will really speed up read queries. Also, look at your most frequently used SQL queries, and time them with different data sets. Adjust the queries by adding keys to tables, especially in WHERE clauses. Also, you may want to look into completely revamping queries.
Multi-part queries involving lots of roundtrips between the script and the database are a no-no. Consider replacing these queries with SQL joins. Joins are relatively fast if done properly. Next, you may want to tr
Re:It depends on how the queries work. (Score:1)
Re:It depends on how the queries work. (Score:2)
some MySQL optimization tips (Score:5, Interesting)
With properly normalized data, on fast, current, commodity hardware (10krpm drives for instance), using InnoDB, you can pretty easily push MySQL into the 5 to 10 million records-per-table range before you start really needing a bigger relational database engine. This assumes no more than 1% of your data is needing to be updated per day. Staying with GPL database software is a really smart thing to do: you don't know how much time and money gets spent on just negotiating with Oracle over their licenses: it is anything but simple. Small business web sites cease to be "small business" when they grow beyond of
A non-trivial part of my business is in advising companies in how to get the most out of MySQL. Replication is one part of that, but having the right data structure for scalability is really key. Want more? Ask around at: www.phpconsulting.com
Re:some MySQL optimization tips (Score:3, Insightful)
- At the least stripe the volumes across multiple disks.
- The system should have the virtual memory partition/swap on a separate disk alone. If not controller.
- SCSI drives are notorius for utililizing less resources.
- Run the database on raw device, not on some filesystem.
Re:some MySQL optimization tips (Score:2)
Err, do you mean stripe sets or do you mean RAID?
Add enough RAM and throw out the swap space. RAM is (still) cheap these days. With the advance of serial ATA, having the swap on a different controller should not be too difficult.
Notorius? Don't you mean "famous", maybe?
Re:some MySQL optimization tips (Score:2)
Re:some MySQL optimization tips (Score:1)
Re:Just... (Score:4, Funny)
Re-design the schema... (Score:5, Insightful)
280,000 records, even for MySQL, isn't that much and indicates that performance is being driven down either by tiny hardware or more likely...
1) Badly optimised queries
2) Poor index selection and maintainance
3) Generally poor schema design
It might also be that queries should be cross table with sub-queries(not a MySQL strong point).
9/10 poor database performance is due to bad database design.
Uh, 280,000 users (Score:2)
Re:Uh, 280,000 users (Score:2)
1) impressive tuning
2) considerable one-machine hardware
3) consistent design choices
Again, your mileage may vary
Re:Re-design the schema... (Score:2)
Yes I just finished Data Structures, no I don't know mySql
Re:Re-design the schema... (Score:2)
Hashed indexes (especially when the data and index key are co-located on the same page) are great for OLTP systems, but are otherwise a cast iron bitch to maintain.
Yes I just finished Data Structures, no I don't know mySql
If you wind up a "DP" developer writing lots of SQL, you'll never have to implement things like b-trees and hashes.
You will, though, need to grok the positive & negative consequences of each kind of data structure, and how those
A plea. (Score:5, Insightful)
How well normalized is the schema? Mostly reads? Writes? Both? 280,000 users? So what. Do you mean simultaneous users or are only 2 on at a time? Are they accessing a single 100 record table or lots of large tables? Are they indexed properly? What is the OS, memory, disk, processor...? How much processing is required of the DB vs. the front-end. Have you run into any specific problems [sql-info.de] that might indicate that a different db might be more appropriate. What have you tried and what was the result?
To the editors: Please reject Ask Slasdot questions from posters who can't be bothered to provide the most basic background info.
This is Slashdot. I would like to believe that the typical reader could be rather more technically erudite.
This is precisely what the poster needed. (Score:2)
"it depends" (Score:5, Insightful)
The ABSOLUTELY MOST IMPORTANT THING is to set up some benchmarks that reflect your usage patterns. Once you have some solid benchmarks, you can set up a farm of test machines and start benchmarking, adjusting, benchmarking, adjusting, over and over until you've got the performance you need. I can't stress this enough. You need a good, automated benchmark system to get you the first 85-90% of the way. The last 10% has to be done "in the field" unless your benchmarks are REALLY good.
Generally, you want to minimize disk usage time on your databases. Everything else is just gravy. Make sure you've got some FAST disks for your MySQL boxes, and make sure they are striped RAID (or whatever your benchmarks show as being the fastest). Choose your filesystem (ext3, reiser, etc) the same way: use the one that benchmarks the fastest.
Next, there are lots of things you can tune in MySQL. For instance, did you know there's a "query cache" that will save the results of queries, indexed by the SQL query text? In *some* situations, it can be very useful. In others, it actually degrades performance. First learn about MySQL's various knobs and get them tuned.
Next, you might need to distribute reads to more mirrored DBs and/or to application-level caching like memcached. Depending on your app, this can give you a 100x speed increase.
Next, you might want to partition your database, if your data is suited for it. For instance, all queries for customers in Idaho go to a separate machine just for the idaho customers. All your application goes through a DB access layer that selects the right machine.
Basically, you need to get the "main loop" down: benchmark, adjust, benchmark, adjust, etc., etc, and then start trying things out!
The same goes for PostgreSQL.
But whatever you do, the LAST thing you want to do is mess with your database intregity. If anybody tells you to "turn off constraints" or "denormalize for performance", they are idiots. Your primary goal should always be data integrity! If you've got a real app, with real paying customers, and real valuable data (i.e., not a blog or something), you can't afford to throw 30 years of database best practices out the window to get a 5% speed increase. Today's SQL databases unfortunately don't even begin to implement even the most basic relational features, but that doesn't mean you shouldn't try. Just a tip...I've made plenty of consulting dollars fixing the mess people left when they started valuing performance over data integrity.
Re:"it depends" (Score:2, Informative)
Re:"it depends" (Score:1)
make sure they are striped RAID
Your primary goal should always be data integrity!.
I'm confused... you want the OP to use striped disks, yet you want the OP to have data integrity as a primary goal. That's like asking for a raw boiled egg.
Re:"it depends" (Score:2)
I'm confused... you want the OP to use striped disks, yet you want the OP to have data integrity as a primary goal. That's like asking for a raw boiled egg.
Striping with data integrity is called RAID 10 or RAID 5, both of which provide better data integrity than a single disk. RAID 10 if you need good write performance, and RAID 5 if you are on a budget and only need good read performance. Heck, even mirroring will increase read speed.
Very different than a raw boiled egg...
Use static content (Score:1)
Date searches may not work as you think (Score:2)
Certain reports would kill the system - make it stop entirely for minutes at a time. What I discovered was that this kind of query
select (fields) from calendar where date like '2005-08-15%'
was horribly slow. Instead, use
select (fields) from calendar where date >= '2005-08-15' and date date_add('2005-08-15', interval
Re:Date searches may not work as you think (Score:2, Informative)
Re:Date searches may not work as you think (Score:2)
Marginally off topic.
I use a 4GL Database called Progress. (Not to be confused with postgresql).
Recently in code I was writing I needed to check the status of a flag, basicly to ignore all previously processed records in a queue.
Easy enough...
FOR EACH tablename WHERE NOT tablename.Processed
After a hundred thousand records were created the query was taking ages to run, in spite of tablename.Processed being an indexed logical field. I didn't realize it when I wrote the code, but a NOT statement disables index
Re:Date searches may not work as you think (Score:2, Interesting)
Re:Date searches may not work as you think (Score:2)
As I mentioned, it is a queue of records. Once the records are processed the flag is toggled.
As for the hundred thousand records, it wasn't the rule for this table, it was an except which was created by a combination of factors outside of my control, it was however a good stress test.
sqlrelay (Score:3, Interesting)
High Performance MySQL (Score:5, Informative)
Check out the High Performance MySQL book for info on how to speed it up. Most of it's probably obvious for the hardcore DBA guy, but I found it useful:
http://www.oreilly.com/catalog/hpmysql/ [oreilly.com]
A few things, and alternative technologies (Score:3, Informative)
A few things too look at:
- If there is excessive or improper locking being done (i.e.: do you really need to lock a table to update a record that could only possibly be updated one at a time?)
- If queries can be made less complex
- Indexing. You should become intimate with how indexing works and the various ways of setting it up
- Caching infrequently changed content on the front-end (i.e. generate static web pages that don't change too often rather than dynamically creating them constantly).
- de-normalize your tables if it improves performance. Don't worry nobody's looking
Also, look into some lighter-weight DB & DB-related technologies: HSqlDB, SQLite, C-JDBC, BerkeleyDB, SQLRelay, to name a few. Granted some aren't distributed, but again, not knowing the architecture, some data may be lazily replicated out from the master.
Also, I can't find it now, but I read a while back that MySQL was adopting an open-sourced in-memory DB from a company (Ericcson?) that may be available separately. You also may want to look into something like LDAP (OpenLDAP) if the app is very read-heavy.
Very Simple Solution (Score:2)
Account Names Server
a-c db01
d-g db02
h-j db03
The key is to choose your boundaries so that each DB server holds a roughly equal number of account.
If you have a really, really busy dat
Re:Very Simple Solution (Score:1)
A distributed approach may well be a good idea, but once you start to distribute, you have to consider what should happen if one of the machines falls down.
Re:Very Simple Solution (Score:2)
Re:Very Simple Solution (Score:1)
upgrade from the 486 (Score:2)
(provide more statistics than just how many records are in the user database, and we can probably help you a little bit. Otherwise, we're pretty crippled. With 280,000 user records, it doesn't sound like there's a whole hell of a lot happening on it to choke off a powerful machine, not if the software that's accessing things is done right. So, need more info.)
ask the source (Score:4, Interesting)
http://www.mysql.com/company/contact/ [mysql.com]
Their Enterprise contracts are probably a bit much for your friend's needs, but they may offer single-incident support for optimization and tuning assistance.
If he doesn't mind delving into DBA-land, he may want to buy a book. If he values the time it would take him to get up to speed and would rather spend it on other pursuits, it may well be worth the money to get some help.
Either way, he'll have to spend something (time or money) -- it's a question of how much his time is worth to him.
In general (Score:2)
Optimizing any system involves two steps, one analytical and one creative. The analytical step is determinining exactly where all that time is going. Sometimes it isn't the 80/20 rule, it's the 99/1 rule. The creative step is figuring out how to avoid spending so much time there, either by avoiding unnecessary trips (caching or just cleaner programming), or to speed up the process in question.
If you're lucky, the bottleneck may be in a single tier. It could be as si
How about an inexpensive O'Reilly book? (Score:2)
Optimizing Oracle Performance [oreilly.com] by Cary Millsap with Jeff Holt
It's time to re-think the overall design (Score:2, Insightful)
Something I recently found... (Score:3, Interesting)
I am in the process of re-doing my website using PHP and MySQL. My new site will be complete DB driven, to the point that the page content is driven and built from PHP stored in the DB. My goal is to be able to update the website from anywhere in the world with a web connection. I am custom writing this system, rather than use a pre-existing CMS or other blogging system (and there were quite a few that were tempting) - because I wanted to learn PHP and MySQL by doing, rather than by observing.
Anyhow, one of my editors was slowing down on an update - that is, when I clicked "update" to update the site, it was taking a long time to update the database. Various tests indicated that it wasn't PHP with the issue, but running 'top' on my dev box indicated that the apache process was thrashing on these updates. I checked the code, and here is what I discovered:
In my update code, I was issuing a SQL insert for each field in a record, where I was updating multiple fields on the same record, rather than doing an insert with all the fields to be updated in the SQL statement. If I had 10 fields to update, that was 10 INSERTS, instead of the single I should have been doing. As I said, this was a bone-headed move I won't be doing again in the future. Once I corrected the issue, my performance shot up immediately on the update.
I would imagine that the same could be true of any simple SELECT - select out all the fields (and only those fields) you need at one shot, then loop thru the records building your output (whatever it is). Optimize the queries well, too (a misplaced pair of parentheses can make a WORLD of difference in some cases).
In short, keep the number of queries to the backend as short and sweet as possible, reducing the load (and thrashing) on the backend. This should be common sense design, but sometimes in the thrill and rush to build something, programmers forget this, and it can easily cause issues down the line (I was lucky in that I caught it very early in my design of the system).
Good luck, and I hope this helps...
Review Application Code (Score:1)
I m late in this thread but... (Score:1)