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

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 :) ибо у самой пока с ними сложно(

Заранее благодарна ^_^
 

prolis

Новичок
[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]
ЗЫ: судя по характеру задачи, количество записей легко перевалит за миллион, тем не менее структура расположения данных выбрана крайне неразумно для такой цели.
 

Gas

может по одной?
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
 

Artison

Новичок
Большое спасибо за ответы и помощь!

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`)
- зачем эти индексы нужны?
 

Artison

Новичок
ответы на вопросы :)
1. вы не верно поняли ситуацию - это не проекты (проекты как раз в отдельной), это таблица внешних ссылок проекта (с какого сайта, какой ключ, на какую страницу проекта ведет и тп).
2. вы имеете ввиду тип text или? можете подробнее объяснить? по этому полю выборки не ведутся. а значение поля может быть более 255 символов
3. по ip не производится выборок, поэтому в данном случае метод хранения не критичен
4. yaca - нет. остальные лучше сделать Int?
5. краткость, т.е. привычка :) на производительность вроде бы
6. для быстроты выборки - варианты значений очень небольшие, без индексов вроде бы дольше выборка происходит. по ip правда можно наверное убрать.

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

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