First, the MD5 on the headline field should be unique enough for your purposes. There is no real need to query against the headline field in addition to the headline_hash. Secondly, is there some reason you are querying a 900 character field? I mean, what user would possibly type in 900 characters to match against for the body of an article? Consider dropping this altogether as an index field, unless you need FULLTEXT querying against it.
Consider placing an index strictly on the headline_hash and url_hash fields, separately:
CREATE INDEX idx_headline_hash ON articles (headline_hash);
CREATE INDEX idx_url_hash ON articles (url_hash);
Depending on the type of query you are running, adding the article id field to these indexes might increase performance as well, since a covering index would be created for joins, alleviating the need for record lookups into the .MYD file:
CREATE INDEX idx_headline_hash ON articles (headline_hash, id);
CREATE INDEX idx_url_hash ON articles (url_hash, id);
Use a UNION to enable MySQL to utilize the indexes on both the headline_hash and url_hash. In your case, I believe you're just trying to check for existence:
SELECT 1 FROM articles
WHERE url_hash = md5(?url)
LIMIT 1
UNION
SELECT 1 FROM articles
WHERE headline_hash = md5(?headline)
LIMIT 1;
Jay Pipes
Community Relations Manager, North America, MySQL Inc.
Got Cluster?
http://www.mysql.com/cluster
Personal:
http://jpipes.com