На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania RSS
msm.ru
! информация о разделе
user posted imageДанный раздел предназначается исключительно для обсуждения вопросов использования языка запросов SQL. Обсуждение общих вопросов, связанных с тематикой баз данных - обсуждаем в разделе "Базы данных: общие вопросы". Убедительная просьба - соблюдать "Правила форума" и не пренебрегать "Правильным оформлением своих тем". Прежде, чем создавать тему, имеет смысл заглянуть в раздел "Базы данных: FAQ", возможно там уже есть ответ.

Модераторы: Pr0[)!9Y, Akina, JoeUser
  
> SELECT к двум хостам (MYSQL)
Добрый день.

Я немного упрощу описание проблемы и заменю названия для наглядности.

У меня два сервера, на первом хранятся МУЖИКИ с id-шниками. На втором БАБЫ тоже с id-шниками.

На первом сервере, в таблицу с МУЖИКАМИ первого сервера добавил ручками столбец "WomanId" и забил туда по нужным мне соответствиям(ну скажем это жены ихние) id-шники БАБ со второго сервера.

Получилось что-то типа такого:
ManId____ManName_______WomanId
1025_____Игорь_________541
1021_____Борис_________645

Мне нужно получить на первом сервере данные в таком виде:
Имя мужика/Имя бабы

Как я делал:
ExpandedWrap disabled
    $result1 = mysqli_query($server1, 'SELECT ManId, ManName, WomanId FROM bd1.Man;');
    while ($row1 = mysqli_fetch_array($result1)) {
        $result2 = mysqli_query($server2, 'SELECT WomanName FROM bd2.Woman WHERE WomanId ='.$row1[2].';');
        while ($row2 = mysqli_fetch_array($result2)) {
            echo $row1[1]." ".$row2[0]."</br>";  
        }
    }


Получаю нужные мне "Имя мужика/Имя бабы"
Но, мужиков у меня больше 1000, в итоге в цикле отправляется 1000+ запросов к второму серверу с бабами, это работает, но очень медленно.

На mssql получал список баб одним запросом:
Формировал xml: <row id = "1025">541</row> <row id = "1021">645</row>
и отправлял запрос к второму серверу "declare @xml xml SET @xml='<row id = "1025">541</row> <row id = "1021">645</row>...

Т.е. я прописывал в xml соответствия мужик_id/баба_id и второй сервер мне возвращал данные в таком виде
ManId(который я же ему и отправлял в xml)/и имя бабы
1025/Света
1021/Люся

После чего, слинковать баб к мужикам по id из запроса плевое дело.
Можно как нибудь так же, одним запросом на mysql сделать?(Модифицировать базы нельзя only read, настраивать базы, прописывать линки нельзя, only php и only read)
Ну или может еще какие варианты есть?

Спасибо.
На первый сервер шлёшь запрос

ExpandedWrap disabled
    SELECT ManId, ManName, WomanId
    FROM bd1.Man;


Полученные данные валишь в массив.

Все полученные WomanId собираешь в одну переменную, разделяя значения запятыми, и шлёшь на второй сервер запрос

ExpandedWrap disabled
    SELECT WomanId, WomanName
    FROM bd2.Woman
    WHERE WomanId IN (WomanId-1, WomanId-2, ... , WomanId-N);


Полученные данные валишь во второй массив.

Затем объединяешь массивы в один по равенству поля WomanId.

Всё.

PS. Возможная ошибка - попытка вставить переменную со списком как параметр. В этом случае список будет обрамлён кавычками и воспринят как один длинный литерал, а не список.
Есть претензии ко мне как к модератору? читайте Правила, разделы 5 и 6, и действуйте соответственно.
Есть претензии ко мне как к участнику? да ради бога.
Не нравятся мои ответы? не читайте их.
В общем, берегите себя. Нервные клетки не восстанавливаются.
Цитата Akina @
Затем объединяешь массивы в один по равенству поля WomanId.

А как объеденить то?))
Тут сортировка нужна сравнивать ID то что пришло от баб и те бабские ID которые у мужиков были.
Потому что приходит ответ не сортированный ну никак, да и даже если бы был сортированный, у меня мужиков к примеру тысяча, а ID баб подбиты 900 к примеру - так что в цикле тоже не рассортируешь - нужен алгоритм посложнее.
А сортировка, поверь, по скорости практически тоже самое, что юзать так, как я написал. Ну мб чуть быстрее. Делал я так. Не варик.

Варик - это получить WomanID вместе с отправляемыми ManID - тогда можно сразу найти нужный тип/массив по ManID и записать туда WomanName.

Т.е. я отправляю на бабский сервер xml с мужскими и женскими ID, джойню с таблицей Woman и получаю ответ из бд и из xml. Из xml ManID, из бд WomanName.
Тогда мне ответ приходит такой: ManID|WomanName, мне не надо сортировать, я просто ложу WomanName по ManID.
Вот что я бы хотел, но у меня проблема с синтаксисом - не могу переписать запрос с mssql на mysql.

Вот то, что я пытался сваять из рабочего mssql запроса и нужного мне mysql. Но ошибка, как исправить не знаю...
$qer формирую когда получаю ответ от первого сервера.
Примерно так:
ExpandedWrap disabled
    $qer.=('<row id = "'.$id_one[$row[0]].'">'.$id_two[$row[0]].'</row>');



ExpandedWrap disabled
    DECLARE xml TEXT;
    SET xml='<rows>".$qer."</rows>';
    SELECT Art.SortKey, t1.PRICE, t2.VALUE FROM
    (select b.value('@id' , 'int') [SortKey], b.value('.' , 'varchar(50)') [ArtNo] FROM @xml.nodes('/rows/row') a(b) )as Art LEFT JOIN
    b_catalog_price AS t1 ON t1.PRODUCT_ID = Art.ArtNo LEFT JOIN
    b_iblock_element_property AS t2 ON t2.IBLOCK_ELEMENT_ID = t1.PRODUCT_ID AND t2.IBLOCK_PROPERTY_ID = 47
Сообщение отредактировано: Rzonex -
Цитата Rzonex @
А как объеденить то?

Понятия не имею - я в ПХП ни ухом ни рылом... но вроде как там функций для обработки массивов море, неужто не найдётся объединение по ключу?
Цитата Rzonex @
А сортировка, поверь, по скорости практически тоже самое, что юзать так, как я написал.

Фигню говоришь. Добавь в запрос нужный ORDER BY, и получишь результат уже сортированным. И поверь, это будет гораздо быстрее, чем сортирить на клиенте (кстати, уж сортирить массивы ПХП сто пудов умеет).
Есть претензии ко мне как к модератору? читайте Правила, разделы 5 и 6, и действуйте соответственно.
Есть претензии ко мне как к участнику? да ради бога.
Не нравятся мои ответы? не читайте их.
В общем, берегите себя. Нервные клетки не восстанавливаются.
Цитата Akina @
Фигню говоришь.

Я имел в виду сортировку в самом php.
У меня объявлен тип, в котором я храню всю нужную информацию. Идентификатором этого типа является ManID.
Вот пришел мне запрос с голыми WomanName, ну и WomanID. А мне каждую бабу эту нужно записать в php тип. Но куда?
А туда где WomanID из запроса будет равен WomanID типа.
Как это сделать? Самое простое - создать еще тип, добавить в него все поля из запроса, и крутить сравнение в цикле - если совпало,
записывать один тип в другой и удалять тот который из запроса был создан. В итоге получаем простейшую сортировку.
А без этого, рассортировать запрос в тип я не могу.
И такие костыли я уже делал. Оно плохо работает, оно мне не по душе, оно мне не нравится.
А мне нравится послать xml к бабам и получить в лтвете баб и id мужиков, чтобы я сразу мог результат в php записать в нужный мне тип.
Сообщение отредактировано: Rzonex -
Цитата
Мне нужно получить на первом сервере данные в таком виде:
Имя мужика/Имя бабы

вот тебе костыль вариант 1
ExpandedWrap disabled
        
        $result1 = mysqli_query($server1, 'SELECT ManId, ManName, WomanId FROM bd1.Man;');
        $result2 = mysqli_query($server2, 'SELECT WomanId, WomanName FROM bd2.Woman;');
        for ($res1 = array(); $tmp = $result1->fetch_array(MYSQLI_ASSOC);) $res1[] = $tmp;
        for ($res2 = array(); $tmp = $result2->fetch_array(MYSQLI_ASSOC);) $res2[] = $tmp;
        foreach($res1 as $man){
          foreach($res2 as $woman){
            if ($man['WomanId'] == $woman['WomanId']) {
              echo $man['ManName']." ".$woman['WomanName']."</br>";
              break;
            }
          }
        }

вот тебе костыль вариант 2
ExpandedWrap disabled
        $result1 = mysqli_query($server1, 'SELECT ManId, ManName, WomanId FROM bd1.Man;');
        $result2 = mysqli_query($server2, 'SELECT WomanId, WomanName FROM bd2.Woman;');
        $womans = array();
        while ($row2 = mysqli_fetch_array($result2)) { $womans[$row2['WomanId']] = $row2['WomanName']; }
        while ($row1 = mysqli_fetch_array($result1)) {
          echo $row1['ManName']." ".$womans[$row1['WomanId']]."</br>";  
            }
Сообщение отредактировано: Gonarh -
Цитата Rzonex @
Я имел в виду сортировку в самом php.

ЗАЧЕМ? Оставь решение задачи сортировки тому, кто умеет это делать лучше - серверу MySQL.
Есть претензии ко мне как к модератору? читайте Правила, разделы 5 и 6, и действуйте соответственно.
Есть претензии ко мне как к участнику? да ради бога.
Не нравятся мои ответы? не читайте их.
В общем, берегите себя. Нервные клетки не восстанавливаются.
Цитата Akina @

Так я этого и добиваюсь))) Но что бы мне не делать сортировку в php - мне нужны данные от мускула в виде ManId/WomanName

Цитата Gonarh @
вот тебе костыль вариант 1

У меня на обоих сайтах овер 1000 записей. Тут у тебя два вложенных цикла, это миллион итераций. Это будет работать, но это костыль.
Добавлю, что у меня не два сайта а 4. Это при 1000 записей 4 милиона итераций, при 2000 будет уже 16 лямов, рост в геом. прогрессии.
Если оптимизировать, то нужно делать правильно. А ваш вариант это костыль, уж простите.

Ну разве нельзя отправить на второй сервер запрос с xml с ManID|WomanId?
Чтобы он вернул ManId|WomanName???
Сообщение отредактировано: Rzonex -
Второй вариант - двухпроходный цикл

Добавлено
Цитата Rzonex @
Это при 1000 записей 4 милиона итераций, при 2000 будет уже 16 лямов, рост в геом. прогрессии.

Не будет там 16 млн итераций.

Добавлено
Цитата Rzonex @
Ну разве нельзя отправить на второй сервер запрос с xml с ManID|WomanId?

Отправить то ты можешь, только там ManID нахер не нужон.
Цитата Rzonex @
Ну разве нельзя отправить на второй сервер запрос

Можно.
Цитата Rzonex @
с xml с ManID|WomanId?

Можно, но бессмысленно. MySQL не понимает запросов в XML-формате.

Озвучьте версию второго MySQL. Можно крупно - 5 или 8?
Есть претензии ко мне как к модератору? читайте Правила, разделы 5 и 6, и действуйте соответственно.
Есть претензии ко мне как к участнику? да ради бога.
Не нравятся мои ответы? не читайте их.
В общем, берегите себя. Нервные клетки не восстанавливаются.
Цитата Gonarh @
Отправить то ты можешь, только там ManID нахер не нужон.

Нет, он там нужон. А для чего? Чтобы он вернулся вместе с WomanName, чтобы мне не сортировать в php потом, не делать вложенных циклов.
Я так делал на mssql это работало очень быстро.

Цитата Gonarh @
Не будет там 16 млн итераций.

Да будет меньше, 16 млн, это если искомая запись всегда будет последней в цикле.
Я не хочу так делать, у меня скоро пять сайтов будет, а может еще больше. Нужен оптимизированный вариант...
Цитата Rzonex @
Модифицировать базы нельзя only read, настраивать базы, прописывать линки нельзя, only php и only read

Заведите свой, третий, MySQL-сервер, и с него аттачьтесь к первым двум. Обойдётесь одним простым запросом.

The FEDERATED Storage Engine
Есть претензии ко мне как к модератору? читайте Правила, разделы 5 и 6, и действуйте соответственно.
Есть претензии ко мне как к участнику? да ради бога.
Не нравятся мои ответы? не читайте их.
В общем, берегите себя. Нервные клетки не восстанавливаются.
Цитата Akina @
Озвучьте версию второго MySQL. Можно крупно - 5 или 8?

У меня скоро пять сайтов будет. Везде разные версии...
Цитата Akina @
Заведите свой, третий, MySQL-сервер, и с него аттачьтесь к первым двум. Обойдётесь одним простым запросом.

Не могу. На сервере, где запускаю скрипт отключен удаленный доступ к бд, точнее он есть но через ssh туннель.
Цитата Akina @
Можно, но бессмысленно. MySQL не понимает запросов в XML-формате.

Очень печально. Может все-таки можно как-нибудь отправить запрос с ManID и соответствующими им WomanID? Чтобы в ответе сохранялся порядок ManID/WomanName?
Это все что нужно, это будет работать очень быстро, я так делал...
Сообщение отредактировано: Rzonex -
Возможное решение-костыль.

Делаем первый запрос на первый сервер.
ExpandedWrap disabled
    SELECT ManId, ManName, WomanId FROM bd1.Man;

Получаем, к примеру
ManIdManNameWomanId
11Петя111
12Коля112
13Вася113

На основании этих данных формируем запрос на второй сервер, который выглядит так:
ExpandedWrap disabled
    SELECT t1.ManName, bd2.WomanName
    FROM     ( SELECT 'Петя' ManName, 111 WomanId
               UNION ALL
               SELECT 'Коля', 112
               UNION ALL
               SELECT 'Вася', 113
              ) AS t1
    LEFT JOIN bd2.Woman ON t1.WomanId = bd2.WomanId;

и получаем в ответ
ManNameWomanName
ПетяКлава
КоляОля
ВасяNULL

Последний NULL означает, что Вася ещё пока неженатый.
Есть претензии ко мне как к модератору? читайте Правила, разделы 5 и 6, и действуйте соответственно.
Есть претензии ко мне как к участнику? да ради бога.
Не нравятся мои ответы? не читайте их.
В общем, берегите себя. Нервные клетки не восстанавливаются.
Цитата Akina @
Возможное решение-костыль.

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

Это песня, это сказка :D Работает очень быстро и никакой это не костыль, а имхо оптимальное решение.

Спасибо большое Akina!
Сообщение отредактировано: Rzonex -
1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
0 пользователей:


Рейтинг@Mail.ru
[ Script Execution time: 0,1641 ]   [ 20 queries used ]   [ Generated: 17.07.19, 17:33 GMT ]