Я добавил рекламные объявления на свой веб-сайт, у которых есть достаточно условий для встречи перед тем, как доставить пользователю просмотра. Вот подробное описание:Оптимизировать часто выполняемый запрос
Эти поля, которые требуют поясняющие:
start
по умолчанию «0000-00-00», и это указывает, является ли объявление было еще уплаченной или нет. Когда платеж по объявлению принимается, start
устанавливается на следующий день или в любую дату, когда клиент выбирает.
impresssions
составляет соответственно остальные впечатления от рекламы
impressions_total
и impressions_perday
самообъясняющие
и другие поля, используемые в запросе лишь поля, VALIDATE попадает ли пользователь в спецификации реклама-х слуховой аппарат
Объявление должно быть оплачено, чтобы начать показ в первую очередь, однако его можно установить для начала в будущем, поэтому значение start
будет установлено, но объявление не должны появляться до того, как пришло время. Тогда, поскольку клиенты могут ограничить количество показов в день, мне нужно подобрать только рекламные объявления с достаточным количеством показов на текущий день. Например, если реклама запущена в 30/08/2013 с 10 000 показов и 2000 показов в день, то она не должна появляться сегодня (31/08/2013), если она имеет менее 6000 показов, потому что это вторая день кампании. Кроме того, если срок действия периода составляет 5 дней и 5 дней, реклама должна быть показана независимо от оставшихся показов. Тогда есть и те другие сравнения, которые подтверждают, что пользователь подходит для показа этого объявления, и все это становится настолько сложным.
Я не очень хорошо разбираюсь в mysql, хотя мне удалось создать рабочий запрос, и я очень обеспокоен его оптимизацией. Я почти уверен, что методы, которые я использовал, очень неэффективны, но я не мог найти лучший способ в Интернете. Вот почему я задаю этот вопрос здесь, может ли кто-нибудь помочь мне улучшить производительность этого запроса?
SELECT `fields`,
FROM `ads`
WHERE (`impressions`>0 && `start`!='0000-00-00')
AND `start`<CURDATE() AND
(
`impressions`>(`impressions_total`-(CONVERT(CURDATE()-date(`start`), UNSIGNED)*`impressions_perday`))
OR (`impressions_total`/`impressions_perday` < CURDATE()-date(`start`))
-- this is the part where I validate the impressions for the day
-- and am most concerned that I haven't built correctly
)
AND
(
(
(YEAR(NOW())-YEAR("user's birthday") BETWEEN `ageMIN` AND `ageMax`)
AND (`sex`=2 OR `sex`="user's gender")
AND (`country`='' OR `country`="user's country")
) OR `applyToUnregistered` = 1
)
ORDER BY $random_order -- Generate random order pattern
Схема:
CREATE TABLE `ads` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`headline` varchar(25) NOT NULL,
`text` varchar(90) NOT NULL,
`url` varchar(50) NOT NULL,
`country` varchar(2) DEFAULT '0',
`ageMIN` tinyint(2) unsigned NOT NULL,
`ageMax` tinyint(2) unsigned NOT NULL,
`sex` tinyint(1) unsigned NOT NULL DEFAULT '2',
`applyToUnregistered` tinyint(1) unsigned NOT NULL DEFAULT '0',
`creator` int(10) unsigned NOT NULL,
`created` int(10) unsigned NOT NULL,
`start` date NOT NULL,
`impressions_total` int(10) unsigned NOT NULL,
`impressions_perday` mediumint(8) unsigned NOT NULL,
`impressions` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=27 DEFAULT CHARSET=utf8
** Не указывайте/не возвращайте имена столбцов. ** Они добавляют только визуальный беспорядок и это еще один способ сделать синтаксические ошибки. Единственная причина, по которой вы нуждаетесь в них, - это то, что у вас есть имя столбца, которое является зарезервированным словом, и использование имен столбцов, которые являются зарезервированными словами, является ужасной идеей, так что это две вредные привычки, которые вы можете избежать сразу. –
Оптимизация сложна без схемы. Пожалуйста, опубликуйте синтаксис create table. – zevra0
@ zevra0 schema добавлено –