Модераторы: skyboy

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> проблема с запросом 
:(
    Опции темы
awers
  Дата 3.1.2007, 21:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1465
Регистрация: 22.3.2006
Где: Россия, Таганрог

Репутация: 1
Всего: 31



Добрый вечер.

Суть такая: существует оооогромный запрос, с условиями выборки 
Код

WHERE `to` LIKE '%' AND `to` NOT LIKE '8%' AND `to` NOT LIKE '0%' OR `to` LIKE '824%' OR `to` LIKE '88634%';


если добавляю туда условие `date` > '2007' выбирает вообще непонятно что ...
Код

WHERE `date` > '2007' AND `to` LIKE '%' AND `to` NOT LIKE '8%' AND `to` NOT LIKE '0%' OR `to` LIKE '824%' OR `to` LIKE '88634%';


Помогите подалуйста решить проблемс. 

Заранее благодарен, Адам.
PM MAIL WWW ICQ Skype   Вверх
skyboy
Дата 3.1.2007, 23:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



все свои or-условия тебе, по всей видимости, надо обрамит скобками

Добавлено @ 23:15 
иначе будут выбираться только те строки, где:
а) дата больше 2007 и "`to` LIKE '%'"(что, по видимому, означает: "в поле `to` есть хоть какие-то символы")
б) выполняются все остальные условия
а, как я понимаю, надо так:
и дата больше 2007, и поля содержать хоть что-то из перечисленного
PM MAIL   Вверх
awers
Дата 3.1.2007, 23:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1465
Регистрация: 22.3.2006
Где: Россия, Таганрог

Репутация: 1
Всего: 31



вообще мне надо чтоб выбиралось по date в интервале с INT1 по INT2, 
phone начиналось с чего угодно кроме 8 за исключением 824,88634 и 0

мож я что-то не так пишу... а HAVING тормозит все жутко просто ...
надо выкручиваться с WHERE ...
PM MAIL WWW ICQ Skype   Вверх
skyboy
Дата 3.1.2007, 23:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



каким боком тут having?  smile 
Код

WHERE `date` between '07-12-2006' AND '06-08-2007' AND (LEFT(`to`,1) <> '8' OR LEFT(`to`,4) = '824' OR LEFT(`to`,5) = '88634')

Между нами, подмножество "или 0" входит в подмножетсво "начиналось с чего угодно, кроме 8", потому ставить дополнительное условие не надо. Тем более не надо использовать шаблонные функции поиска(REGEXP, LIKE, RLIKE) там, где можно обойтись обычной "резкой"
PM MAIL   Вверх
awers
Дата 4.1.2007, 00:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1465
Регистрация: 22.3.2006
Где: Россия, Таганрог

Репутация: 1
Всего: 31



MySQL не осилил. После 35 минут 98% загрузки проца - умер. Жаль.

хех... сорри. это оказывается MySQL не осилил 50000 строк. Что делать ведь в переди сотни тысяч?

--------

и ещё. наши запросы выполняются на таблице 2800 записей одно и то-же время. 3,7 сек.
могу привести запрос полностью, если не страшно  smile 

Это сообщение отредактировал(а) awers - 4.1.2007, 00:36
PM MAIL WWW ICQ Skype   Вверх
skyboy
Дата 4.1.2007, 00:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



awers, чем не подошёл? какая версия? дапм таблицы брось. и распиши запрос полностью.
как это - 50000 не осилил?  smile 

Это сообщение отредактировал(а) skyboy - 4.1.2007, 00:36
PM MAIL   Вверх
awers
Дата 4.1.2007, 00:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1465
Регистрация: 22.3.2006
Где: Россия, Таганрог

Репутация: 1
Всего: 31



ну, т.с. бойтесь smile
Код

start transaction;


CREATE TEMPORARY TABLE t1 AS SELECT `phone` AS `ph` , 
(SELECT `svm` FROM `tarif` WHERE `id` = (SELECT `tarif` FROM `users` WHERE `phone` = `ph` )) AS `cena` , 
CEILING( `time` /1000 /60 ) AS `min` , 
CEILING( `time` /1000 /60 ) * (SELECT `svm` FROM `tarif` WHERE `id` = ( SELECT `tarif` FROM `users` WHERE `phone` = `ph` ) ) AS `summ` , 
`to` , `date`,
(SELECT COUNT( * ) FROM `statistic` WHERE `phone` = `ph`) AS `cou` , 
(SELECT `name`FROM `users` WHERE `phone` = `ph`) AS `fio`, 
(SELECT `dogovor` FROM `users` WHERE `phone` = `ph`) AS `dogovor`,
(SELECT `vkm` FROM `tarif` WHERE `id` = (SELECT `tarif` FROM `users` WHERE `phone` = `ph` )) as `vkm`,
(SELECT `svm` FROM `tarif` WHERE `id` = (SELECT `tarif` FROM `users` WHERE `phone` = `ph` )) as `svm`,
(SELECT `abp` FROM `tarif` WHERE `id` = (SELECT `tarif` FROM `users` WHERE `phone` = `ph` )) as `abp`
FROM `statistic` 
#WHERE `to` LIKE '%' AND `to` NOT LIKE '8%' AND `to` NOT LIKE '0%' OR `to` LIKE '824%' OR `to` LIKE '88634%';
WHERE (LEFT(`to`,1) <> '8' OR LEFT(`to`,4) = '824' OR LEFT(`to`,5) = '88634');


insert into `t3` SELECT `date`,`fio` , `dogovor` , 
SUM( `summ` ) AS `summ` , 
`ph` , COUNT( * ) AS `cu` , 
`cou`,  `cou` - COUNT(*) as `mg`,
`vkm`,`abp`,`svm`, SUM(`min`) as `min`,
(SUM(`min`) - `vkm`) * `svm` + `abp` AS `result`
FROM `t1` 
GROUP BY `ph` 
LIMIT 10000 ;



COMMIT;



Прикрепил файлик, вся БД.

Самому страшно смотреть, но пока самый простой выход...

Это сообщение отредактировал(а) awers - 4.1.2007, 00:39

Присоединённый файл ( Кол-во скачиваний: 2 )
Присоединённый файл  atc.rar 41,42 Kb
PM MAIL WWW ICQ Skype   Вверх
skyboy
Дата 4.1.2007, 00:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



не страшно. думаю, оптимизатор сам приводит шабонные выражения к нешаблонным. впрочем, если охота полагаться на милось оптимизатора  - пожалуйста smile
попробуй ещё так написать:
Код

WHERE `date` between '07-12-2006' AND '06-08-2007' AND `to` REGEXP "^([^8]|(88634|824))"

если я не перепутал, должно давать тот же результат. и записано короче. но время выполнения.....

Добавлено @ 00:41 
хм. а подзапросы в качестве полей - это нормально? как в explain - ключи используются?
    немного нетактичный вопрос - чем такое лучше использования join'ов? быстрее? компактнее? или  чего не усмотрел и там логика другая?

Добавлено @ 00:42 
и зачем вообще - временная таблица? она потом ещё используется?
PM MAIL   Вверх
awers
Дата 4.1.2007, 00:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1465
Регистрация: 22.3.2006
Где: Россия, Таганрог

Репутация: 1
Всего: 31



Ты погляди базу... Може я чего то просто сам промаргал .. в SQL`e не профан..
PM MAIL WWW ICQ Skype   Вверх
skyboy
Дата 4.1.2007, 00:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



хм smile ладно, те виднее smile

Добавлено @ 00:48 
нету у меня дома mysql, чтоб тестировать. нету smile
PM MAIL   Вверх
awers
Дата 4.1.2007, 00:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1465
Регистрация: 22.3.2006
Где: Россия, Таганрог

Репутация: 1
Всего: 31



Ну мож тогда посоветуеш чего?
PM MAIL WWW ICQ Skype   Вверх
skyboy
Дата 4.1.2007, 01:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



awers, я не понимаю, что ты выбираешь столь сложным запросом. мало того - я даже не понимаю, что представляет собой твоя база. догадываюсь по названию - что-то связанное с АТС. биллинговая система? 
PM MAIL   Вверх
awers
Дата 4.1.2007, 01:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1465
Регистрация: 22.3.2006
Где: Россия, Таганрог

Репутация: 1
Всего: 31



Код

SELECT users.id AS `user_id` , users.name AS `fio` , users.adres AS `adres` , users.phone AS `us_phone` , users.dogovor AS `dogovor` , tarif.name AS `tarif` , tarif.abp AS `abp` , tarif.vkm AS `vkm` , tarif.svm AS `svm` , atc.name AS `atc` , (

SELECT sum( ceiling( `time` /1000 /60 ) ) 
FROM `statistic` 
WHERE `to` REGEXP "^([^8]|(88634|824))"
AND `phone` = `us_phone` 
) AS `time` , (

SELECT count( * ) 
FROM `statistic` 
WHERE `phone` = `us_phone` 
) AS `smin` , (

SELECT count( * ) 
FROM `statistic` 
WHERE `to` REGEXP "^([^8]|(88634|824))"
AND `phone` = `us_phone` 
) AS `cmin` , (

SELECT (
`time` - `vkm` 
) * `svm` + `abp` 
) AS `sum` 
FROM `users` 
LEFT JOIN `tarif` ON `users`.`tarif` = `tarif`.`id` 
LEFT JOIN `atc` ON `users`.`atc` = `atc`.`id` 


Чем все кончилось ... вот только можно ли ещё как нить упростить конструкцию??

[/code]

Добавлено @ 01:29 
Да.. биллинг.
Код

CREATE TABLE `atc` (\n  `id` int(11) NOT NULL auto_increment,\n  `name` text NOT NULL,\n  PRIMARY KEY  (`id`)\n) ENGINE=MyISAM DEFAULT CHARSET=cp1251


Код

CREATE TABLE `statistic` (\n  `id` int(11) NOT NULL auto_increment,\n  `phone` int(11) NOT NULL default '0',\n  `date` datetime default '0000-00-00 00:00:00',\n  `to` text NOT NULL,\n  `time` int(11) NOT NULL default '0',\n  `parsed` int(1) NOT NULL default '0',\n  PRIMARY KEY  (`id`)\n) ENGINE=MyISAM DEFAULT CHARSET=cp1251


Код

CREATE TABLE `tarif` (\n  `id` int(11) NOT NULL auto_increment,\n  `name` text NOT NULL,\n  `abp` float NOT NULL default '0',\n  `vkm` int(11) NOT NULL default '0',\n  `svm` decimal(8,2) NOT NULL default '0.00',\n  PRIMARY KEY  (`id`)\n) ENGINE=MyISAM DEFAULT CHARSET=cp1251


Код

CREATE TABLE `users` (\n  `id` int(11) NOT NULL auto_increment,\n  `name` text NOT NULL,\n  `adres` text NOT NULL,\n  `phone` int(11) NOT NULL default '0',\n  `dogovor` text NOT NULL,\n  `tarif` int(11) NOT NULL default '0',\n  `atc` int(11) NOT NULL default '0',\n  `dop` text NOT NULL,\n  PRIMARY KEY  (`id`)\n) ENGINE=MyISAM DEFAULT CHARSET=cp1251


думаю наполнение ненужно ...

Добавлено @ 01:31 
Как полезно иногда читьать мануалы.. ктоб занл ... JOIN ))
PM MAIL WWW ICQ Skype   Вверх
skyboy
Дата 4.1.2007, 01:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 41
Всего: 260



аааа... эээ... REGEXP я привел в пример, чтоб показать, как могут тормозить запрос шаблонные конструкции. неужто работает с приемлимой скоростью?
не совсем понял, что делает запрос smile но мне показалось, что в том запросе ну совсем разнородная информация. Так? может, стОит разбить запрос? ну, поясни хоть, что к чему. 
не совсем понял, как заложена логика подсчета стоимости. точнее - где?
PM MAIL   Вверх
awers
Дата 4.1.2007, 01:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1465
Регистрация: 22.3.2006
Где: Россия, Таганрог

Репутация: 1
Всего: 31



Код

SELECT users.id AS `user_id` , users.name AS `fio` , users.adres AS `adres` , users.phone AS `us_phone` , users.dogovor AS `dogovor` , tarif.name AS `tarif` , tarif.abp AS `abp` , tarif.vkm AS `vkm` , tarif.svm AS `svm` , atc.name AS `atc` , (


# в таблице statistic время хранится в миллисекундах, так уж АТС сделана. Мы выбираем сумму минут всех звонков которые мы имеем право тарифицировать
SELECT sum( ceiling( `time` /1000 /60 ) ) 
FROM `statistic` 
WHERE `to` REGEXP "^([^8]|(88634|824))"
AND `phone` = `us_phone` 
) AS `time` , (

# Общее кол-во звонков
SELECT count( * ) 
FROM `statistic` 
WHERE `phone` = `us_phone` 
) AS `smin` , (

# Кол-во звонков, которые мы тарифицируем
SELECT count( * ) 
FROM `statistic` 
WHERE `to` REGEXP "^([^8]|(88634|824))"
AND `phone` = `us_phone` 
) AS `cmin` , (

# считаем абонплату исходя из формулы: количиство минут - количество минут включеных в пакет * цена минуты + абонентская плата.

SELECT (
`time` - `vkm` 
) * `svm` + `abp` 
) AS `sum` 
FROM `users` 
LEFT JOIN `tarif` ON `users`.`tarif` = `tarif`.`id` 
LEFT JOIN `atc` ON `users`.`atc` = `atc`.`id` 


Добавлено @ 01:59 
теперь надо компактно добавить условие `date` к запросам из `statistic` ... а компактно не получается smile

Добавлено @ 02:02 
кстати да. в случае с "рег.ехр" время 0,1056
а с (LEFT(`to`,1) <> '8' OR LEFT(`to`,4) = '824' OR LEFT(`to`,5) = '88634')
время 0,0373
PM MAIL WWW ICQ Skype   Вверх
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | MySQL | Следующая тема »


 




[ Время генерации скрипта: 0.0622 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.