Сложные выборки из базы, нужна помощь

  • Автор темы Автор темы Artison
  • Дата начала Дата начала

Artison

Новичок
Сложные выборки из базы, нужна помощь

Нужно помощь по построению сложной выборки из бд, чтобы она при этом саму бд не очень грузила :)
Нужно учитывать, что кол-во записей может быть достаточно большое от 100 тысяч и выше, может быть конечно и малое, но лучше рассчитывать, что может быть и большое)))

Итак, есть таблица:

PHP:
CREATE TABLE `project_links` (
  `project_link_id` int(11) NOT NULL AUTO_INCREMENT,
  `project_id` int(11) NOT NULL,
  `project_link_url` text NOT NULL,
  `project_link_ip` varchar(20) NOT NULL,
  `project_link_yaca` varchar(255) NOT NULL,
  `project_link_tic` varchar(255) NOT NULL DEFAULT '-',
  `project_link_pr` varchar(255) NOT NULL DEFAULT '-',
  `project_link_date` date NOT NULL,
  `project_link_title` varchar(255) NOT NULL,
  `project_link_anchor` varchar(255) NOT NULL,
  `project_link_found` enum('Y','N') NOT NULL DEFAULT 'N',
  `project_link_checked` enum('Y','N') NOT NULL DEFAULT 'N',
  `project_link_error_connect` enum('Y','N') NOT NULL DEFAULT 'N',
  `project_link_to_url` varchar(255) NOT NULL,
  `project_link_site` varchar(255) NOT NULL,
  PRIMARY KEY (`project_link_id`),
  KEY `project_link_site` (`project_link_site`),
  KEY `project_link_anchor` (`project_link_anchor`),
  KEY `project_link_tic` (`project_link_tic`),
  KEY `project_link_ip` (`project_link_ip`),
  KEY `project_link_yaca` (`project_link_yaca`),
  KEY `project_link_pr` (`project_link_pr`),
  KEY `project_link_found` (`project_link_found`),
  KEY `project_link_error_connect` (`project_link_error_connect`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8;

Для известного нам project_id нужно выбрать все записи, где с каждого project_link_site (адрес сайта) не более 10-ти project_link_url (адрес страницы сайта), у которых разные project_link_anchor (текст ссылки). хотелось бы сделать все это красивым запросом, заодно поучиться у спецов по запросам MySQL :) ибо у самой пока с ними сложно(

Заранее благодарна ^_^
 
[sql]
select project_id, project_link_site
from project_links
where project_id=XXX
group by project_id,project_link_site
having count(distinct concat(project_link_url,project_link_anchor))<10
[/sql]
ЗЫ: судя по характеру задачи, количество записей легко перевалит за миллион, тем не менее структура расположения данных выбрана крайне неразумно для такой цели.
 
SELECT project_link_site, COUNT(DISTINCT CONCAT(project_link_url,project_link_anchor)) AS cnt
FROM project_links
WHERE project_id = [ID]
GROUP BY project_link_site
HAVING cnt <= 10

вроде как-то так, если нужны полные данные, то сделай этот запрос вложенным:

select ... from
( select из начала сообщения
) as t
join project_links on t...

писал и не видел варианта prolis'а
 
Большое спасибо за ответы и помощь!

prolis, какую структуру хранения данных Вы бы порекомендовали, можете объяснить свою точну зрения?

заранее благодарна ^_^
 
Artison хорошо:
1. Есть сущности со своими атрибутами: проект, сайт проекта, страница сайта, ссылка на странице сайта. Почему они все денормализованы в одну таблицу?
2. `project_link_url` text NOT NULL - такой формат не предназначен для оперативного доступа к значению поля, тем не менее он активно используется в запросах.
3. `project_link_ip` varchar(20) NOT NULL
- поищите по форуму, как лучше хранить IP
4. `project_link_yaca` varchar(255) NOT NULL,
`project_link_tic` varchar(255) NOT NULL DEFAULT '-',
`project_link_pr` varchar(255) NOT NULL DEFAULT '-',
- это целочисленные поля
5. project_link_found` enum('Y','N') NOT NULL DEFAULT 'N',
`project_link_checked` enum('Y','N') NOT NULL DEFAULT 'N',
`project_link_error_connect` enum('Y','N') NOT NULL DEFAULT 'N',
- на вкус и цвет конечно, но чем бинарный тип для бинарных данных не устроил?
6. KEY `project_link_tic` (`project_link_tic`),
KEY `project_link_ip` (`project_link_ip`),
KEY `project_link_yaca` (`project_link_yaca`),
KEY `project_link_pr` (`project_link_pr`),
KEY `project_link_found` (`project_link_found`),
KEY `project_link_error_connect` (`project_link_error_connect`)
- зачем эти индексы нужны?
 
ответы на вопросы :)
1. вы не верно поняли ситуацию - это не проекты (проекты как раз в отдельной), это таблица внешних ссылок проекта (с какого сайта, какой ключ, на какую страницу проекта ведет и тп).
2. вы имеете ввиду тип text или? можете подробнее объяснить? по этому полю выборки не ведутся. а значение поля может быть более 255 символов
3. по ip не производится выборок, поэтому в данном случае метод хранения не критичен
4. yaca - нет. остальные лучше сделать Int?
5. краткость, т.е. привычка :) на производительность вроде бы
6. для быстроты выборки - варианты значений очень небольшие, без индексов вроде бы дольше выборка происходит. по ip правда можно наверное убрать.

хотела еще спросить эти изменения в структуре какой реальный прирост к производительности могут дать?

и насколько быстрее работает выборка по типу int в отличии от varchar?
 
Сверху