Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Помогите оптимизировать такой запрос / 13 сообщений из 13, страница 1 из 1
30.11.2015, 23:16:07
    #39116841
Помогите оптимизировать такой запрос
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
SELECT SQL_CALC_FOUND_ROWS `id`, `opponent_1_id`, `opponent_2_id`, `title` AS `topic`,
								
								(CASE DATE_FORMAT(`date`, '%Y%-%m-%d')
									WHEN CURDATE() THEN DATE_FORMAT(`date`, 'сегодня, %H:%i')
									WHEN SUBDATE(CURDATE(), INTERVAL 1 DAY) THEN DATE_FORMAT(`date`, 'вчера, %H:%i') ELSE  DATE_FORMAT(`date`, '%e %M, %H:%i')
								END) AS `datePrint`
								
								IF(`opponent_1_id` != ?,
									
									(CASE (SELECT COUNT(*) FROM `owners` WHERE `id` = `opponent_1_id`)
										WHEN 1 THEN 'owner'
										WHEN 0 THEN 'company'
									END),
									
									(CASE (SELECT COUNT(*) FROM `owners` WHERE `id` = `opponent_2_id`)
										WHEN 1 THEN 'owner'
										WHEN 0 THEN 'company'
									END)
									
								) AS `opponentType`,

																
								IF(`opponent_1_id` != ?,
									
									(CASE (SELECT COUNT(*) FROM `owners` WHERE `id` = `opponent_1_id`)
										WHEN 1 THEN (SELECT `name` FROM `owners` WHERE id = `opponent_1_id`)
										WHEN 0 THEN (SELECT `title` FROM `companies` WHERE id = `opponent_1_id`)
									END),
									
									(CASE (SELECT COUNT(*) FROM `owners` WHERE `id` = `opponent_2_id`)
										WHEN 1 THEN (SELECT `name` FROM `owners` WHERE id = `opponent_2_id`)
										WHEN 0 THEN (SELECT `title` FROM `companies` WHERE id = `opponent_2_id`)
									END)
									
								) AS `opponent`,
								
											
								(SELECT COUNT(*) FROM `messages` AS `m` 
									WHERE `m`.`status` = 0	
										   AND `m`.`topic` = `t`.id		
									AND `m`.`user` != ?								
								) AS `unread`,
								
								
								IF(`opponent_1_id` != ?,
									
									(CASE (SELECT COUNT(*) FROM `owners` WHERE `id` = `opponent_1_id`)
										WHEN 1 THEN (SELECT `img` FROM `owners` WHERE id = `opponent_1_id`)
										WHEN 0 THEN (SELECT `img` FROM `companies` WHERE id = `opponent_1_id`)
									END),
									
									(CASE (SELECT COUNT(*) FROM `owners` WHERE `id` = `opponent_2_id`)
										WHEN 1 THEN (SELECT `img` FROM `owners` WHERE id = `opponent_2_id`)
										WHEN 0 THEN (SELECT `img` FROM `companies` WHERE id = `opponent_2_id`)
									END)
									
								) AS `img`,
								
								
								IF(`opponent_1_id` != ?,
									
									(CASE (SELECT COUNT(*) FROM `owners` WHERE `id` = `opponent_1_id`)
										WHEN 1 THEN (SELECT `sex` FROM `owners` WHERE id = `opponent_1_id`)
									END),
									
									(CASE (SELECT COUNT(*) FROM `owners` WHERE `id` = `opponent_2_id`)
										WHEN 1 THEN (SELECT `sex` FROM `owners` WHERE id = `opponent_2_id`)
									END)
									
								) AS `sex`,	
									
																	
								
							
							FROM `messages_topics` AS `t`		
							
							WHERE (`opponent_1_id` = ? OR opponent_2_id = ?)
							
							ORDER BY `unread` DESC, `date` DESC, `title` LIMIT ?, ?



Сам запрос просто, и выводит топики от сообщений (где есть дата, заголовк и id двух людей кто участвует в разговоре)
Но вот что получить все данные, получается много подзапросов, чтобы определить какой пользователь из какой таблицы, и какой пользователь текущий а какой оппонент + получить по ним доп инфу

Скажите можно ли что-то придумать?
...
Рейтинг: 0 / 0
30.11.2015, 23:25:11
    #39116849
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать такой запрос
Питерский11
Код: sql
1.
2.
3.
(CASE (SELECT COUNT(*) FROM `owners` WHERE `id` = `opponent_1_id`)
  WHEN 1 THEN (SELECT `sex` FROM `owners` WHERE id = `opponent_1_id`)
END),

Это что за кошмар? Почем не просто
Код: sql
1.
(SELECT `sex` FROM `owners` WHERE id = `opponent_1_id`)
...
Рейтинг: 0 / 0
30.11.2015, 23:27:55
    #39116850
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать такой запрос
Питерский11
Код: sql
1.
WHERE (`opponent_1_id` = ? OR opponent_2_id = ?)

Разделите запрос на две части отдельно для каждого случая, а потом объедините их с помощью UNION ALL.
Подозреваю, что итоговая конструкция станет сильно проще и быстрее.
...
Рейтинг: 0 / 0
30.11.2015, 23:36:12
    #39116858
Помогите оптимизировать такой запрос
Тут ситаация такая

что есть два вида пользвоателей Организации и владельцы

(CASE (SELECT COUNT(*) FROM `owners` WHERE `id` = `opponent_1_id`)
WHEN 1 THEN (SELECT `sex` FROM `owners` WHERE id = `opponent_1_id`)
END),

так вот у владельцев есть в своей таблице поле пол
а у организаций нет
...
Рейтинг: 0 / 0
30.11.2015, 23:37:56
    #39116861
Помогите оптимизировать такой запрос
Еще нюанс, мы заранее не знаем, кто из этих пользователей написал и кому написали. И заранее не знаем тип этого пользователя, чтобы выбрать его имя из таблицы
...
Рейтинг: 0 / 0
30.11.2015, 23:49:25
    #39116865
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать такой запрос
Питерский11Тут ситаация такая

что есть два вида пользвоателей Организации и владельцы

(CASE (SELECT COUNT(*) FROM `owners` WHERE `id` = `opponent_1_id`)
WHEN 1 THEN (SELECT `sex` FROM `owners` WHERE id = `opponent_1_id`)
END),

так вот у владельцев есть в своей таблице поле пол
а у организаций нетНу и что? В переводе на русский у вас в запрос написано "если выбирается одна запись, то выбираем поле из этой записи". Зачем так писать? Почему не сразу "Выбираем поле из нужной записи".
...
Рейтинг: 0 / 0
01.12.2015, 00:00:25
    #39116867
Помогите оптимизировать такой запрос
miksoft,

Ну это понятно, если я исправлю особо ничего не изменит логика корявая, куча подзапросов.

Скажите а можно ли как-то так

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
SELECT SQL_CALC_FOUND_ROWS `t`.`id`, `opponent_1_id`, `opponent_2_id`, `title` AS `topic`,
									`e`.`name` AS `title`,
									`e`.`img` AS `img`,
									`e`.`type` AS `type`,
									`e`.`sex` AS `sex`,
								
								(CASE DATE_FORMAT(`date`, '%Y%-%m-%d')
									WHEN CURDATE() THEN DATE_FORMAT(`date`, 'сегодня, %H:%i')
									WHEN SUBDATE(CURDATE(), INTERVAL 1 DAY) THEN DATE_FORMAT(`date`, 'вчера, %H:%i') ELSE  DATE_FORMAT(`date`, '%e %M, %H:%i')
								END) AS `datePrint`
							
							FROM `messages_topics` AS `t`	
																							
							inner join
							(
								
								(CASE (SELECT COUNT(*) FROM `owners` WHERE `id` = `opponent_2_id`)
									WHEN 1 THEN (SELECT `name`, `img`, `sex`, 'owner' AS `type` FROM `owners` WHERE id = `opponent_2_id`)
									WHEN 0 THEN (SELECT `title`, `img`, 'null' AS `sex`, 'company' AS `type` FROM `companies` WHERE id = `opponent_2_id`)
								END)
								
							) AS `e`
							
							on 
								 `e`.`id` = `t`.`opponent_2_id`									
								
							
							 WHERE `opponent_1_id` = ?
							
							
							ORDER BY `date` DESC, `title` LIMIT ?, ?
...
Рейтинг: 0 / 0
01.12.2015, 00:18:01
    #39116875
Помогите оптимизировать такой запрос
Питерский11,

С одной таблицей в inner join получается ) и нет никаких подзапросов.

Но тут весь вопрос, что надо выбирать из какой таблицы делать inner join, если владелец из owner и если организаиця то из companies
...
Рейтинг: 0 / 0
01.12.2015, 06:01:15
    #39116920
скукотища
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать такой запрос
Питерский11,
можно как-то так.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
SELECT SQL_CALC_FOUND_ROWS 
    t.id
    , t.opponent_1_id
    , t.opponent_2_id
    , t.title topic
    , if(o.id, o.name, c.title) title
    , if(o.id, o.img, c.img) img
    , if(o.id, o.owner, c.company) type
    , if(o.id, o.sex, null) sex
    
    , DATE_FORMAT(t.date, 
            case DATEDIFF(CURRENT_DATE(), t.date)
            when 0 then 'сегодня, %H:%i'
            when 1 then 'вчера, %H:%i'
            else        '%e %M, %H:%i'
            end
      ) datePrint
      
FROM 
    messages_topics t
    left join owners o 
        on o.id = t.opponent_2_id
    left join companies c 
        on c.id = t.opponent_2_id

WHERE ...
ORDER BY ...
LIMIT ...
...
Рейтинг: 0 / 0
01.12.2015, 12:16:58
    #39117189
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать такой запрос
Питерский11,
разбей на два запроса с union all, у тебя подзапросы тоже пополам пробиться должны.

также полагаю некоторые запросы можно превратить в join ы.
...
Рейтинг: 0 / 0
01.12.2015, 12:17:41
    #39117191
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать такой запрос
Питерский11Еще нюанс, мы заранее не знаем, кто из этих пользователей написал и кому написали. И заранее не знаем тип этого пользователя, чтобы выбрать его имя из таблицы
так узнай...
...
Рейтинг: 0 / 0
01.12.2015, 12:21:08
    #39117195
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать такой запрос
Питерский11miksoft,

Ну это понятно, если я исправлю особо ничего не изменит логика корявая, куча подзапросов.

Скажите а можно ли как-то так

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
SELECT SQL_CALC_FOUND_ROWS `t`.`id`, `opponent_1_id`, `opponent_2_id`, `title` AS `topic`,
									`e`.`name` AS `title`,
									`e`.`img` AS `img`,
									`e`.`type` AS `type`,
									`e`.`sex` AS `sex`,
								
								(CASE DATE_FORMAT(`date`, '%Y%-%m-%d')
									WHEN CURDATE() THEN DATE_FORMAT(`date`, 'сегодня, %H:%i')
									WHEN SUBDATE(CURDATE(), INTERVAL 1 DAY) THEN DATE_FORMAT(`date`, 'вчера, %H:%i') ELSE  DATE_FORMAT(`date`, '%e %M, %H:%i')
								END) AS `datePrint`
							
							FROM `messages_topics` AS `t`	
																							
							inner join
							(
								
								(CASE (SELECT COUNT(*) FROM `owners` WHERE `id` = `opponent_2_id`)
									WHEN 1 THEN (SELECT `name`, `img`, `sex`, 'owner' AS `type` FROM `owners` WHERE id = `opponent_2_id`)
									WHEN 0 THEN (SELECT `title`, `img`, 'null' AS `sex`, 'company' AS `type` FROM `companies` WHERE id = `opponent_2_id`)
								END)
								
							) AS `e`
							
							on 
								 `e`.`id` = `t`.`opponent_2_id`									
								
							
							 WHERE `opponent_1_id` = ?
							
							
							ORDER BY `date` DESC, `title` LIMIT ?, ?




еще проблема -limit. выбираться все записи, сртируются по дате, потом берется топ X.

что бы сразу не задать фильтр по дате?

это много важнее всех подзапросов, если ты не понимаешь ...
...
Рейтинг: 0 / 0
01.12.2015, 12:22:07
    #39117199
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите оптимизировать такой запрос
Питерский11Питерский11,

С одной таблицей в inner join получается ) и нет никаких подзапросов.

Но тут весь вопрос, что надо выбирать из какой таблицы делать inner join, если владелец из owner и если организаиця то из companies

разбей еще на два запроса под union all...
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Помогите оптимизировать такой запрос / 13 сообщений из 13, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]