Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / MySQL Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Выборка из 650к  [new]
didgik
Member

Откуда:
Сообщений: 605
Напишу-ка в отдельную тему чтоб милиарды не засорять. ) Да и вдруг решение найдется.
Вобщем есть табличка новостей на данный момент 665к записей:
-- Версия сервера: 5.5.28-log
-- Версия PHP: 5.4.7

--
-- Структура таблицы `news`
--

CREATE TABLE IF NOT EXISTS `news` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `NAME` varchar(255) CHARACTER SET cp1251 NOT NULL DEFAULT '',
  `title` varchar(255) CHARACTER SET cp1251 NOT NULL,
  `DATE_` varchar(11) CHARACTER SET cp1251 NOT NULL,
  `SECTION_ID` int(11) NOT NULL DEFAULT '0',
  `COUNTRY_ID` int(11) NOT NULL DEFAULT '0',
  `country_id2` int(3) NOT NULL,
  `AGENCY_ID` int(11) NOT NULL DEFAULT '0',
  `PUB` tinyint(4) NOT NULL DEFAULT '0',
  `pub_otr` int(11) DEFAULT '0',
  `pub_fo` int(11) NOT NULL DEFAULT '0',
  `TEXT` mediumtext CHARACTER SET cp1251 NOT NULL,
  `fo_id` int(11) NOT NULL DEFAULT '0',
  `wregion_id` int(3) NOT NULL,
  `changedate` int(11) NOT NULL,
  `day` tinyint(2) unsigned NOT NULL,
  `month` tinyint(2) unsigned NOT NULL,
  `year` int(10) unsigned NOT NULL,
  `date` date NOT NULL,
  `adddate` date DEFAULT NULL,
  `cat_a` tinyint(1) NOT NULL,
  `checked` tinyint(1) NOT NULL DEFAULT '0',
  `lang` enum('ru','en','fr') CHARACTER SET cp1251 NOT NULL DEFAULT 'ru',
  `person` varchar(255) CHARACTER SET cp1251 NOT NULL,
  `keywords` text CHARACTER SET cp1251 NOT NULL,
  PRIMARY KEY (`ID`),
  KEY `SECTION_ID` (`SECTION_ID`),
  KEY `COUNTRY_ID` (`COUNTRY_ID`),
  KEY `AGENCY_ID` (`AGENCY_ID`),
  KEY `PUB` (`PUB`),
  KEY `date` (`date`),
  KEY `lang` (`lang`),
  KEY `fo_id` (`fo_id`),
  KEY `country_id2` (`country_id2`),
  KEY `changedate` (`changedate`),
  KEY `person` (`person`),
  KEY `wregion_id` (`wregion_id`),
  FULLTEXT KEY `name` (`NAME`,`TEXT`,`keywords`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8

Таблица Строки Тип Сравнение Размер Фрагментировано
news 665428 MyISAM utf8_general_ci 3.5 ГБ -


Имя индексаТипУникальный УпакованПолеУникальных элементовСравнениеNullКомментарий
PRIMARYBTREE Да Нет ID 665456 A Нет
SECTION_IDBTREE Нет Нет SECTION_ID 27 A Нет
COUNTRY_ID BTREE Нет Нет COUNTRY_ID 237 A Нет
AGENCY_ID BTREE Нет Нет AGENCY_ID 651 A Нет
PUB BTREE Нет Нет PUB 2 A Нет
date BTREE Нет Нет date 3412 A Нет
lang BTREE Нет Нет lang 3 A Нет
fo_id BTREE Нет Нет fo_id 10 A Нет
country_id2 BTREE Нет Нет country_id2 203 A Нет
changedate BTREE Нет Нет changedate 665456 A Нет
person BTREE Нет Нет person 3066 A Нет
wregion_id BTREE Нет Нет wregion_id 5 A Нет
name FULLTEXT Нет Нет NAME TEXT keywords 1 Нет


Тут два нюанса. Во первых нужен MyISAM для полнотекстового поиска, во вторых, так как это новости, обновление идет достаточно часто. Раньше могло вставлятся по 1 новости раз в пять минут, сейчас немного переделали, чтоб вставлялось пачкой и пореже.
8 ноя 12, 16:44    [13440943]     Ответить | Цитировать Сообщить модератору
 Re: Выборка из 650к  [new]
didgik
Member

Откуда:
Сообщений: 605
Тяжелые запросы вида:
SELECT SQL_CALC_FOUND_ROWS
  news.ID AS ns_id, news.date AS ns_date, news.TEXT ns_text, news.country_id AS  country_id,
  news.wregion_id AS wregion, cat_a, fo_id, news.title AS title, news.country_id AS ns_cnt,
  pc2.NAME AS country_name2, news.person AS ns_person, news.section_id AS section_id,
  pc.NAME AS country_name, ns.NAME AS section_name, na.not_send AS not_send,
  na.free AS agency_allowed, na.URI AS agency_url, na.NAME AS agency_name,
  gf.shortname AS fo_name, gw.name AS wregion_name
FROM news
LEFT JOIN parser_country AS pc ON COUNTRY_ID = pc.ID
LEFT JOIN parser_country AS pc2 ON country_id2 = pc2.ID
LEFT JOIN news_section AS ns ON SECTION_ID = ns.ID
LEFT JOIN news_agency AS na ON AGENCY_ID = na.ID
LEFT JOIN geo_fo AS gf ON fo_id = gf.id
LEFT JOIN geo_wregion AS gw ON news.wregion_id = gw.id
JOIN 
  (SELECT id
  FROM news
  WHERE 1 AND news.SECTION_ID =5 AND (news.COUNTRY_ID =118 OR news.country_id2 =118)
    AND news.AGENCY_ID IN (
      SELECT id
      FROM news_agency
      WHERE not_send <>1)
  ORDER BY date DESC
  LIMIT 0 , 50)xx ON news.id = xx.id

Кроме обычных табличек-справочников есть табличка с агенствами news_agency, у неё есть поле not_send. Большей половине юзеров показываются новости только разрешенных агенств, т.е. not_send<>1

Сейчас переписываю подобные запросы в два типа:
SELECT news.id as news_id
FROM news
WHERE ( news.COUNTRY_ID=195 or news.country_id2=195 or fo_id=10)
order by date desc

и
select news.ID AS ns_id, news.date AS ns_date, news.TEXT ns_text, news.country_id AS country_id,
  news.wregion_id as wregion, cat_a, fo_id, news.title as title, news.country_id as ns_cnt,
  pc2.NAME AS country_name2,news.person as ns_person, news.section_id AS section_id,
  pc.NAME AS country_name, ns.NAME AS section_name, na.not_send as not_send, na.free AS agency_allowed,
  na.URI AS agency_url, na.NAME AS agency_name, gf.shortname as fo_name, gw.name AS wregion_name,
  favorites.dt as fav_news_dt
from news LEFT JOIN parser_country AS pc ON COUNTRY_ID = pc.ID 
LEFT JOIN parser_country AS pc2 ON country_id2 = pc2.ID 
LEFT JOIN news_section AS ns ON SECTION_ID = ns.ID 
LEFT JOIN news_agency AS na ON AGENCY_ID = na.ID 
left join geo_fo as gf on fo_id=gf.id 
left join geo_wregion as gw on news.wregion_id=gw.id
left join favorites on (news.id=favorites.news_id and favorites.user_id=2447)
where news.id in(683122,683118,682997,683094,683095,683098,683107,683109,683108,683113,683117,
 683116,683119,683124,683126,683115,682975,682495,682953,682969,682952,682949,682948,682947,
 682946,682976,682979,682981,682642,683096,683092,683025,682991,682990,682987,682983,682982,
 682945,683252,682658,682654,682652,682651,682648,682522) 
order by field(news.id,683122,683118,682997,683094,683095,683098,683107,683109,683108,683113,683117,683116,
 683119,683124,683126,683115,682975,682495,682953,682969,682952,682949,682948,682947,682946,
 682976,682979,682981,682642,683096,683092,683025,682991,682990,682987,682983,682982,682945,
 683252,682658,682654,682652,682651,682648,682522)

Но вот буквально сейчас:
автор
Запрос: 80.62117 сек.
SELECT news.id as news_id
FROM news
WHERE ( news.COUNTRY_ID=195 or news.country_id2=195 or fo_id=10)
order by date desc
limit 45

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE news index_merge COUNTRY_ID, fo_id,country_id2 COUNTRY_ID, country_id2, fo_id 4,4,4 NULL 274736 Using union(COUNTRY_ID, country_id2, fo_id), Using where, Using filesort

вроде бы в данном конкретном случае помогло бы force index(date), но для общего - сомниваюсь
8 ноя 12, 17:15    [13441161]     Ответить | Цитировать Сообщить модератору
 Re: Выборка из 650к  [new]
Arhat109
Member

Откуда: из СССР
Сообщений: 2619
didgik, а чем он "тяжел"?
Каковы размеры приджойниваемых таблиц, особенно страна1, страна2? Не проще их загнать в одну таблицу?

и там, эт-та, кажись левый джойн савсем ни нужен...
8 ноя 12, 17:55    [13441475]     Ответить | Цитировать Сообщить модератору
 Re: Выборка из 650к  [new]
Arhat109
Member

Откуда: из СССР
Сообщений: 2619
didgik, 80сек - круто! Пока писал, не видел остального... что-то там "нето"... раз оптимизатор хочет использовать юнион... мож ему составной индекс "скормить"?
8 ноя 12, 17:58    [13441496]     Ответить | Цитировать Сообщить модератору
 Re: Выборка из 650к  [new]
Arhat109
Member

Откуда: из СССР
Сообщений: 2619
Arhat109,

пардон, он и использует все три и условие по или... да и не сразу заметил, что просмотр "не маловато будет" ... 274 тыс. записей... почти половина таблицы.
8 ноя 12, 18:07    [13441556]     Ответить | Цитировать Сообщить модератору
 Re: Выборка из 650к  [new]
javajdbc
Member

Откуда: Montreal
Сообщений: 8626
didgik,

1. Холли-молли! пожалуйстаставьтепереносстроки
вдлинныеСКЛ-ы . Нуневозможножечитать!!!!!!

2. Срочно замените OR на несколько отдельных СКЛ-ов
соединеных UNION (или UNION ALL, решите по смыслу)

3. Такие СКЛК-ы отлаживайте по ступенчато.
Вукенте все жоинт таблицы, начните с основной и
ее филтров -- отладьте по скорости, ЕКПЛАЙН и индексам.
Потом добавьте одну таблицы, отладьте,
другую таблицу ... и так по одной.

Нападать на 10 таблиц сразу -- и себя и нас запутаете.
8 ноя 12, 18:08    [13441563]     Ответить | Цитировать Сообщить модератору
 Re: Выборка из 650к  [new]
Arhat109
Member

Откуда: из СССР
Сообщений: 2619
javajdbc,

там, в первом запросе, всё вроде как понятно: внутренним селектом вытаскиваем иды новостей, подходящих по условиям фильтров, а потом прилепляем к идам "всё остальное"... одна промблемка: таблиц parser_country - 2шт. и найтись может ИЛИ в той или в другой... левый джойн там по сути нужен только к паре последних таблиц... и то не уверен.

Вот и посоветовал сделать одну табличку и убрать левые джойны. А если вытащить из IN подзапрос, то думаю, что можно ваще без подзапросов делать...
8 ноя 12, 18:28    [13441725]     Ответить | Цитировать Сообщить модератору
 Re: Выборка из 650к  [new]
miksoft
Member

Откуда:
Сообщений: 30453
Arhat109
А если вытащить из IN подзапрос
Это нужно делать в первую очередь!
8 ноя 12, 18:34    [13441765]     Ответить | Цитировать Сообщить модератору
 Re: Выборка из 650к  [new]
javajdbc
Member

Откуда: Montreal
Сообщений: 8626
Arhat109
javajdbc,

там, в первом запросе, всё вроде как понятно: внутренним селектом вытаскиваем иды новостей, подходящих по условиям фильтров, а потом прилепляем к идам "всё остальное"... одна промблемка: таблиц parser_country - 2шт. и найтись может ИЛИ в той или в другой... левый джойн там по сути нужен только к паре последних таблиц... и то не уверен.

Вот и посоветовал сделать одну табличку и убрать левые джойны. А если вытащить из IN подзапрос, то думаю, что можно ваще без подзапросов делать...


У вас хватило терпения читать и разбирать
ПЛОХО-форматированый СКЛ с 10 жоинтами? :-)
без екплейна, без замеров скорости?

Неа, я лучше чаю попью с печеньками :-)
8 ноя 12, 18:40    [13441804]     Ответить | Цитировать Сообщить модератору
 Re: Выборка из 650к  [new]
miksoft
Member

Откуда:
Сообщений: 30453
javajdbc
У вас хватило терпения читать и разбирать
ПЛОХО-форматированый СКЛ с 10 жоинтами? :-)
я попытался улучшить форматирование.
теперь лучше?
8 ноя 12, 18:51    [13441866]     Ответить | Цитировать Сообщить модератору
 Re: Выборка из 650к  [new]
javajdbc
Member

Откуда: Montreal
Сообщений: 8626
miksoft,

Спасибо, вроде хоинты лучше, но
селект блоки все равно уходят
вправо. Хорошо бы авто-форматирование найти,
которы будет вставлят' перевод строки:

-- перед каждым ключевым словом (селецт, фром, ордер, жоинт, АНД, ОР итд)
-- перед каждой запятой
-- желательно удобная идентация

Ну и вообше -- ;юди должны сами понимать что форматирование
улучшает читабельность и вообше желание отвечать.
8 ноя 12, 19:23    [13442054]     Ответить | Цитировать Сообщить модератору
 Re: Выборка из 650к  [new]
didgik
Member

Откуда:
Сообщений: 605
miksoft
javajdbc
У вас хватило терпения читать и разбирать
ПЛОХО-форматированый СКЛ с 10 жоинтами? :-)
я попытался улучшить форматирование.
теперь лучше?

Я вроде пытался более менее отформатировать код, перед постом, может что и пропустил, тогда пардонте!
8 ноя 12, 19:25    [13442062]     Ответить | Цитировать Сообщить модератору
 Re: Выборка из 650к  [new]
didgik
Member

Откуда:
Сообщений: 605
Первый запрос в основном я привел для информации, сейчас от таких избавляюсь переписывая в два, сначала список id, потом саму новость.
Интересно, есть ли смысл в индексах PUB, lang, wregion_id и fo_id, там количество уникальных элементов мало.
Отлаживал я естестсвенно же поэтапно, перебирал несколько вариантов, и остановился пока на этом, но этого оказалось недостаточно )
8 ноя 12, 19:43    [13442151]     Ответить | Цитировать Сообщить модератору
 Re: Выборка из 650к  [new]
miksoft
Member

Откуда:
Сообщений: 30453
javajdbc
miksoft,

Спасибо, вроде хоинты лучше, но
селект блоки все равно уходят
вправо.
А теперь?
Какой ширины окно браузера?
8 ноя 12, 20:13    [13442340]     Ответить | Цитировать Сообщить модератору
 Re: Выборка из 650к  [new]
Arhat109
Member

Откуда: из СССР
Сообщений: 2619
javajdbc,

а я не "читаю"... тупо копирую в EMS Manager ... там уже и разбираю "чё почем"... "чукча не читатель"... :)

пусть лучше автор разъяснит нафига там именно левые джойны, да в таком количестве... особенно ежели учесть, что самый внутренний (в IN) подселект отсекает по тем же условиям что и соединение левых джойнов... какой замысел был?!?

Ежели мы выбираем только те иды новостей, по которым потом ищем в доп. таблицах... ладно ещё, те, которые просто прилепляются... но подозреваю что null там тоже не выбирается... описание -то нужное... :)
8 ноя 12, 20:32    [13442400]     Ответить | Цитировать Сообщить модератору
 Re: Выборка из 650к  [new]
javajdbc
Member

Откуда: Montreal
Сообщений: 8626
miksoft,

на моем экране теперь 100% все показывает без
горизонтального скролинга.

Если я бы делал пост, это было бы:

select 
  news.ID AS ns_id
  , news.date AS ns_date
  , news.TEXT ns_text
  , news.country_id AS country_id
  , news.wregion_id as wregion
  , cat_a, fo_id
  , news.title as title
  , news.country_id as ns_cnt
  , pc2.NAME AS country_name2
  , news.person as ns_person
  , news.section_id AS section_id
  , pc.NAME AS country_name
  , ns.NAME AS section_name
  , na.not_send as not_send
  , na.free AS agency_allowed
  , na.URI AS agency_url
  , na.NAME AS agency_name
  , gf.shortname as fo_name
  , gw.name AS wregion_name
  , favorites.dt as fav_news_dt
FROM 
  news 
  LEFT JOIN parser_country AS pc ON COUNTRY_ID = pc.ID 
  LEFT JOIN parser_country AS pc2 ON country_id2 = pc2.ID 
  LEFT JOIN news_section AS ns ON SECTION_ID = ns.ID 
  LEFT JOIN news_agency AS na ON AGENCY_ID = na.ID 
  left join geo_fo as gf on fo_id=gf.id 
  left join geo_wregion as gw on news.wregion_id=gw.id
  left join favorites on (news.id=favorites.news_id 
                          and favorites.user_id=2447)
where 
  news.id in(683122,683118,682997,683094,683095,683098,683107,
             683109,683108,683113,683117, 83116,683119,683124,683126,683115,
             682975,682495,682953,682969,682952,682949,682948,682947,682946,
             682976,682979,682981,682642,683096,683092,683025,682991,682990,
             682987,682983,682982,682945,683252,682658,682654,682652,682651,
             682648,682522) 
ORDER BY   field(news.id,683122,683118,682997,683094,683095,683098,
                         683107,683109,683108,683113,683117,683116,
                         683119,683124,683126,683115,682975,682495,682953,
                         682969,682952,682949,682948,682947,682946,
                         682976,682979,682981,682642,683096,683092,683025,
                         682991,682990,682987,682983,682982,682945,
                         683252,682658,682654,682652,682651,682648,682522)
8 ноя 12, 20:38    [13442416]     Ответить | Цитировать Сообщить модератору
 Re: Выборка из 650к  [new]
didgik
Member

Откуда:
Сообщений: 605
Arhat109
пусть лучше автор разъяснит нафига там именно левые джойны, да в таком количестве... особенно ежели учесть, что самый внутренний (в IN) подселект отсекает по тем же условиям что и соединение левых джойнов... какой замысел был?!?

Ежели мы выбираем только те иды новостей, по которым потом ищем в доп. таблицах... ладно ещё, те, которые просто прилепляются... но подозреваю что null там тоже не выбирается... описание -то нужное... :)

Левые джоины достают из справочных таблиц всякую инфу типа названия страны, названия агенства и прочее
8 ноя 12, 20:51    [13442458]     Ответить | Цитировать Сообщить модератору
 Re: Выборка из 650к  [new]
netwind
Member

Откуда:
Сообщений: 8774
начнем с того, что 650k новостей это уже не новости, а старости.
удалить, проредить и дело с концом.
8 ноя 12, 20:56    [13442472]     Ответить | Цитировать Сообщить модератору
 Re: Выборка из 650к  [new]
Arhat109
Member

Откуда: из СССР
Сообщений: 2619
didgik,

это - понятно, непонятна именно "левость" джойна. Особливо, что таблица новостей иденты справочников содержит как NOT NULL.

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

1. Поле идента справочника в главной таблице not null -- стало быть идент справочника туда втыкивается обязательно. Я исключаю вариант говно-кода, когда поле not null, но мы пишем 0, или -1, или какое ишо "Г", когда НЕ знаем чего втыкнуть...

2. Внутренним джойном, который в IN() вы гарантированно берете только те новости, которые уже есть с правильными идентами... и?

нафига LEFT JOIN? Ещё раз...

... я так настырно интересуюсь, потому что должно быть понимание чего хотим, и раньше чем оптимизация "как"...
9 ноя 12, 06:23    [13443541]     Ответить | Цитировать Сообщить модератору
 Re: Выборка из 650к  [new]
Arhat109
Member

Откуда: из СССР
Сообщений: 2619
netwind,

угу. Только это "уникальный контент" для Яши... они же честно пишут "пишите для людей"... только чем дальше смотрю на этот поисковик - тем дурнее он мне кажется. Они сами-то знают как он работает?!? :)
9 ноя 12, 06:24    [13443542]     Ответить | Цитировать Сообщить модератору
 Re: Выборка из 650к  [new]
didgik
Member

Откуда:
Сообщений: 605
Arhat109
didgik,

это - понятно, непонятна именно "левость" джойна. Особливо, что таблица новостей иденты справочников содержит как NOT NULL.

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

1. Поле идента справочника в главной таблице not null -- стало быть идент справочника туда втыкивается обязательно. Я исключаю вариант говно-кода, когда поле not null, но мы пишем 0, или -1, или какое ишо "Г", когда НЕ знаем чего втыкнуть...

2. Внутренним джойном, который в IN() вы гарантированно берете только те новости, которые уже есть с правильными идентами... и?

нафига LEFT JOIN? Ещё раз...

... я так настырно интересуюсь, потому что должно быть понимание чего хотим, и раньше чем оптимизация "как"...

Обясняю.
Сначала мы по определеным критериям выбираем список новостей. Соответственно, когда мы выбрали список новостей, мы хотим показать их всех. Соответствено это у нас левая таблица.
Каждая новость в большенстве случаем имеет агенство, соответственно мы лефтджойним табличку с агенствами, лефтджойним так как не хотим потерять из списка новости, у которых агенства нет. Может возникнуть вопрос, зачем мы это делаем два раза, сначала во внутреннем запросе, потом во внешнем. Отвечаю, по эксперементам так вышло быстрее.
Далее у новости часто бывает страна, значит лефтжойним табличку со страной, чтоб узнать название страны, лефтджойним так как не хотим потерять из списка новости, у которых страны нет.
Далее у новости в меньшей вероятности может быть отрасль и еще в более меньшей вероятности может быть вторая страна, соответственно поступаем так, как я писал выше
Если страна - Россия, то у новости может быть федеральный округ, лефтжойним табличку с федеральным округом
Ну и совсем редко бывает макрорегион, с ним поступаем так же.
Соответственно если страны, отрасли и остального нет, то в поле 0, а в справочниках записи с id=0 нету.
9 ноя 12, 08:54    [13443755]     Ответить | Цитировать Сообщить модератору
 Re: Выборка из 650к  [new]
tanglir
Member

Откуда:
Сообщений: 23888
Arhat109
Я исключаю вариант говно-кода, когда поле not null, но мы пишем 0, или -1, или какое ишо "Г", когда НЕ знаем чего втыкнуть...
didgik
Соответственно если страны, отрасли и остального нет, то в поле 0
низачот по телепатии



По сабжу - а попробуйте-ка вот так:
SELECT --поля
FROM 
(SELECT id
 FROM news
 WHERE /*и т.д.*/
) xx 
STRAIGHT_JOIN news ON news.id = xx.id
LEFT JOIN --ну и тут все лефтджойны
, вдруг поможет...
9 ноя 12, 10:08    [13444194]     Ответить | Цитировать Сообщить модератору
 Re: Выборка из 650к  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 26607
Сейчас переписываю подобные запросы в два типа:
SELECT news.id as news_id
FROM news
WHERE ( news.COUNTRY_ID=195 or news.country_id2=195 or fo_id=10)
order by date desc

и
select ...
from news LEFT JOIN parser_country AS pc ON COUNTRY_ID = pc.ID 
...
where news.id in(683122,683118,...) 
order by field(news.id,683122,..)



Ну и очень правильно делаешь.
Можно было бы просто поставить подзапрос в JOIN-е на первое место и форсануть порядок JOIN-ов.
Не знаю, как в MySQL это сделать.



Но вот буквально сейчас:
автор
Запрос: 80.62117 сек.
SELECT news.id as news_id
FROM news
WHERE ( news.COUNTRY_ID=195 or news.country_id2=195 or fo_id=10)
order by date desc
limit 45

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE news index_merge COUNTRY_ID, fo_id,country_id2 COUNTRY_ID, country_id2, fo_id 4,4,4 NULL 274736 Using union(COUNTRY_ID, country_id2, fo_id), Using where, Using filesort

вроде бы в данном конкретном случае помогло бы force index(date), но для общего - сомниваюсь[/quot]

Ну пока там есть limit и тебя устраивает что туда попадут не более 45 последних по дате новостей, то вроде бы всё и ОК.
9 ноя 12, 10:23    [13444290]     Ответить | Цитировать Сообщить модератору
 Re: Выборка из 650к  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 26607
javajdbc
didgik,

2. Срочно замените OR на несколько отдельных СКЛ-ов
соединеных UNION (или UNION ALL, решите по смыслу)


Можно было бы, но если оптимизатор это и сам делает, то зачем ?

javajdbc
Нападать на 10 таблиц сразу -- и себя и нас запутаете.


Да наплевать, там одни тупые JOIN-ы, причём все левые, на селектиность не влияют.
9 ноя 12, 10:26    [13444317]     Ответить | Цитировать Сообщить модератору
 Re: Выборка из 650к  [new]
MasterZiv
Member

Откуда: Питер
Сообщений: 26607
Arhat109
javajdbc,

там, в первом запросе, всё вроде как понятно: внутренним селектом вытаскиваем иды новостей, подходящих по условиям фильтров, а потом прилепляем к идам "всё остальное"... одна промблемка: таблиц parser_country - 2шт. и найтись может ИЛИ в той или в другой... левый джойн там по сути нужен только к паре последних таблиц... и то не уверен.

Вот и посоветовал сделать одну табличку и убрать левые джойны. А если вытащить из IN подзапрос, то думаю, что можно ваще без подзапросов делать...


Убирание левых JOIN-ов ничего не даст, кроме того, что возможно запутает оптимизатор (запутаел ли -- не знаю),
что он будет гадать "а блин не начать ли с этой вот мааааленькой таблички ?"

Чем тебе левые JOIN-ы не угодили ?
ТЫ ж сам правильно сказал -- главное выбрать список последних новостей.
и автор правильно придумал применить индекс по дате и LIMIT 45.

Всё ж хорошо, надо только правильно прописать хинты и всё будет нормально работать.
Оно ж не более 45 записей будет всегда обрабатывать, это ж песня, а не запрос...
9 ноя 12, 10:31    [13444348]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / MySQL Ответить
 
Лучший учебный центр Microsoft!
Новейшие курсы Microsoft SQL Server 2014!
ОЧЕНЬ привлекательные цены на курсы Oracle — от 26 тыс.руб.!
Все курсы по базам данных: Microsoft SQL Server 2014, Oracle, IBM DB2, Access, MySql