Pergunta

I am using new relic to diagnose and fix performance issues with our database. So I have the following query that is the most time consuming.

SELECT * FROM `page_view` 
WHERE `ip_address` = ?s 
  AND `param` = ?n 
  AND NOW() < DATE_ADD(`date`, INTERVAL 1 DAY);

The table structure is as follows:

CREATE TABLE `page_view` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `id_pages` varchar(255) NOT NULL,
  `id_user` int(11) NOT NULL DEFAULT '0',
  `param` varchar(255) NOT NULL DEFAULT '',
  `contract_id` int(10) NOT NULL,
  `listing_type_sid` int(11) DEFAULT NULL,
  `ip_address` varchar(255) DEFAULT NULL,
  `date` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `id_pages` (`id_pages`),
  KEY `id_user` (`id_user`),
  KEY `param` (`param`),
  KEY `contract_id` (`contract_id`)
) ENGINE=MyISAM AUTO_INCREMENT=207 DEFAULT CHARSET=utf8;

Am a novice when it comes to working with queries but I'd appreciate any tips to improve the performance of this one.

Thanks.

Foi útil?

Solução

Implement an appropriate index.

And when possible, don't wrap columns in expressions in predicates, when an equivalent predicate on the bare column is available. For example, this:

NOW() < DATE_ADD(`date`, INTERVAL 1 DAY);

can be replaced by this:

`date` > NOW() + INTERVAL -1 DAY

With the latter form, the right side gets evaluated once, and becomes a literal, and MySQL can consider an index range scan operation on the date column to satisfy the predicate.

With the prior form, that's forcing MySQL to evaluate the expression on the right side and compare the result to the literal for every single row (or, at least, every row that isn't filtered out by some other predicate.)

The most appropriate index for this query would be to have the columns with the equality predicates leading, followed by the column with the inequality:

... ON page_view (ip_address, param, `date`)

Outras dicas

Assuming you have lots of rows in your table, but only some of them relate to a given IP adress and param one suggestion that probably helps speeding up you query: Create a combined index on the fields in the where clause:

create index myindex on page_view(ip_address, param, date)

Then move you date arithmetic away from the date field (subtract one day from now instead of adding it to date column). The new index might decrease insert speed, since there is a new index that must be managed.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top