Master-X
Регистрация
|
Вход
Форум
|
Новости
|
Статьи
Главная
»
Форум
»
Программинг, Скрипты, Софт, Сервисы
»
Тема:
Опять MySQL, сложные запросы и большие объемы данных
Новая тема
Ответить
цитата
20/04/09 в 18:01
webboxxx
уважаемые программеры, помогите задачку решить.
есть файл с урлами:
урл1
урл2
урл3
и так далее. урлов может быть в файле много, порядка 300.000
в таблице mysql есть поля domain, url, flag.
записей в таблице дохрена, скажем порядка полутора миллионов.
файл считывается php-скриптом, для каждого урла определяется его домен, и генерируется запрос для мускуля, которым нужно импортировать урлы в таблицу, но не просто вставить, а с условием:
урл не должен добавляться, если в таблице присутствует запись с таким же доменом, и при этом flag=1.
урл не должен добавляться, если такой же урл уже присутствует в таблице.
в остальных случаях (если такого домена (или урла) нет, или домен есть, но flag при этом равен 0) - запись должна быть добавлена.
из этого следует, что поле url должно быть уникальным, а поле domain уникальным быть не может.
каким образом реализовать такую условную вставку, да еще и чтобы работала она максимально быстро?
в принципе, то условие, что изначально урлы в файле - можно заменить на готовую таблицу с неуникальными полями domain и url.
цитата
20/04/09 в 18:10
Sterx
Цитата:
Если в команде INSERT со строками, имеющими много значений, указывается ключевое слово IGNORE, то все строки, имеющие дублирующиеся ключи PRIMARY или UNIQUE в этой таблице, будут проигнорированы и не будут внесены. Если не указывать IGNORE, то данная операция вставки прекращается при обнаружении строки, имеющей дублирующееся значение существующего ключа. Количество строк, внесенных в данную таблицу, можно определить при помощи функции C API mysql_info().
http://www.mysql.ru/docs/man/INSERT.html
+ играемся where
цитата
20/04/09 в 18:24
webboxxx
where в чистом insert нет. есть в insert .. select .. where, но вот как? where not exists(select count(*) ... ) заставляет задуматься мускуль более чем на 20 минут (дальше вырубил), и это только на таблице с 12к записей...
цитата
20/04/09 в 19:29
Scheme
а зачем "select count(*)"? разве не
INSERT INTO domains
(domain, url, 0)
SELECT url
FROM domain_tmp
WHERE not exists (select * domain_tmp
where domains.url = domain_tmp.url)...
?
правда, для этого придется временную таблицу создавать и закидывать в нее урлы (урл1, урл2) частями.
цитата
20/04/09 в 19:53
webboxxx
ну потому что написано в мане что where not exists(select count(*)...) специально оптимизируется и выполняется быстрее чем *. но даже так выполняется неприемлимо долго, можно даже сказать виснет. так что вложенные запросы не подходят.
цитата
20/04/09 в 22:49
Dr.Syshalt
Пардон, но этот топик напоминает лечение глаукомы по фотографии. Когда речь идет о базах в миллионы записей, тут полно "мелочей", которые могут дать разницу на порядки. Подбор типов колонок (там
хватает тонкостей
), настройка индексов, настройки mysql (кэшей запросов и пр.), выбор бэкенда таблиц. А тут - даже про индексы таблицы ни одного слова, они там вообще есть?
цитата
21/04/09 в 02:45
webboxxx
скажем так - считайте что все делается с нуля, и нет еще никаких таблиц и индексов, потому что эту часть скрипта решил переделать основательно, раньше там совсем все по другому работало. так что очень буду благодарен за советы по организации таблиц, подбору типов полей и индексов для них. а также за статьи по тем же аспектам.
цитата
21/04/09 в 10:51
Lamagro
Оффтопик:
тоже интересно
цитата
21/04/09 в 11:36
asgor
поставь уникальные ключи на
url
domain+flag
и вставляй все без проверок
цитата
21/04/09 в 11:39
asgor
либо же сначала сделай селекты по всем урлам из файла,закинь их куда нить, просто в памяти или во временную таблица, потом сбрасываешь индексы на основной и булком пихаешь, восстанавливаешь индексы.
цитата
21/04/09 в 11:45
Stek
Если надо сделать быстро, то делай по совету asgor'а , будет быстрее всего.
цитата
21/04/09 в 14:53
webboxxx
комрады, ну какие уникальные ключи? прочитайте задачу еще раз. я ж написал - в таблице может быть несколько записей с одинаковым доменом. не было бы этого условия - не было бы вопроса. то что вы мне советуете - сделано уже давно, и сейчас так работает - на уникальных ключах. но условия меняются, и сейчас нужно расширить функционал.
Цитата:
из этого следует, что поле url должно быть уникальным, а поле domain уникальным быть не может.
цитата
21/04/09 в 15:22
begemot
добавь поле "домен" с индексом
а чтобы меньше места ело раздели урл на домен и путь
цитата
21/04/09 в 17:50
asgor
в уникальный ключ можно объединить 2 поля (домен+флаг).
Хотя, да, сорри нельзя так сделать. Иначе разные урлы с одним доменом и флагом 0, тоже не будет добавляться.
цитата
22/04/09 в 11:45
leroy_17
мож просто смысл этого скрипта скажешь для чего он делается,
может там совсем по другому можно организовать без таких напрягов,
я вот тоже недавно переделывал творение одного "мастера" из 1000 таблиц и в каждой по 10к записей типа рефер и еще всякая байда, так у меня вышла табличка с одними цифрами всего на 100 к записей в день и сервак терь летает не то что раньше. Может ты тоже огород городишь ?
цитата
22/04/09 в 20:40
Dr.Syshalt
webboxxx писал:
скажем так - считайте что все делается с нуля, и нет еще никаких таблиц и индексов, потому что эту часть скрипта решил переделать основательно, раньше там совсем все по другому работало. так что очень буду благодарен за советы по организации таблиц, подбору типов полей и индексов для них. а также за статьи по тем же аспектам.
Угу. Это называется "научите меня за один топик на MX создавать оптимальные базы". Тут просто либо немного на другой уровень выходить надо, то есть начать с похода в магазин за толстой книжкой по программированию баз данных, читать и думать, узнавать интересные вещи - что такое "нормализация", например. про которую явно не слыхал тут никто, судя по тому, что никого не удивляет, что записи об одинаковых доменах не вынесены в отдельную таблицу с первичным ключом, а лежат в тех же рядах, что и URL'ы... Ну и всякое прочее интересное можно узнать, что поможет потом, потому как если такие проблемы на этапе инсертов.. то что будет, когда к данным начнут интенсивно обращаться?
Это не сарказм. Просто каждый из нас может упереться в свой предел компетентности в какой-то области. Я, например, не стану, если что, разбирать коробку передач на своей машине сам, я поеду к автослесарю нужному. Хотя свечи могу и сам поменять
))
Новая тема
Ответить
Эта страница в полной версии