За последние 24 часа нас посетил 17461 программист и 1714 роботов. Сейчас ищут 1690 программистов ...

Странная выдача на Select prepare execute

Тема в разделе "PHP и базы данных", создана пользователем processsor, 21 янв 2023.

  1. processsor

    processsor Новичок

    С нами с:
    29 янв 2022
    Сообщения:
    21
    Симпатии:
    0
    PHP запрос

    $query="SELECT * FROM bookings WHERE id=? ";
    $vars=['1'];

    $sth = $this->db->prepare( $query );
    $sth->execute( $vars );
    $rez = $sth->fetchAll();


    Выдает то что надо, но после каждого значения вставляет нумерацию. Что за бред. Без prepare обычным запросом выдает нормально.
    В fetchAll надо чтото ввести чтобы обычно выдавал. а что ?

    Картинка debug:
    https://bit.ly/3Hvkywx

    Например нормальная выдача $rez:

    id=5;
    user=10;
    post=15;

    А он выдает:

    id=5
    0=5
    user=10
    1=10
    post=15
    2=15
     
  2. don.bidon

    don.bidon Активный пользователь

    С нами с:
    28 мар 2021
    Сообщения:
    922
    Симпатии:
    143
  3. processsor

    processsor Новичок

    С нами с:
    29 янв 2022
    Сообщения:
    21
    Симпатии:
    0
    fetchAll( PDO::FETCH_ASSOC )
     
  4. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.839
    Симпатии:
    651
    Нафига FetchAll при выборе по id?
     
  5. processsor

    processsor Новичок

    С нами с:
    29 янв 2022
    Сообщения:
    21
    Симпатии:
    0
    Функция c prepare-execute-fetch универсальная. Query могут приходить разные, не только id.
     
  6. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.839
    Симпатии:
    651
    Надеюсь, у вас есть и спец. ф-ция для выбора по id ;)
     
  7. processsor

    processsor Новичок

    С нами с:
    29 янв 2022
    Сообщения:
    21
    Симпатии:
    0
    Есть куча доп. функций. Включяя по ID. Но и они все использует эту основную функцию.

    Чем fetch лучше fetchall ? В 100 раз быстрее ?
     
  8. don.bidon

    don.bidon Активный пользователь

    С нами с:
    28 мар 2021
    Сообщения:
    922
    Симпатии:
    143
    fetch() достаёт одну запись, зачем жрать лишние ресурсы fetchAll()'ом при выемке одной записи по id?
     
  9. processsor

    processsor Новичок

    С нами с:
    29 янв 2022
    Сообщения:
    21
    Симпатии:
    0
    В запросе на id например есть LIMIT 1 .

    Сильно больше ресурсов жрет ?
     
  10. don.bidon

    don.bidon Активный пользователь

    С нами с:
    28 мар 2021
    Сообщения:
    922
    Симпатии:
    143
    Если поиск по полю с уникальным ключом, необязателен, а так лимиты всегда рекомендуемы, если случайно всю оперативу сожрать не хочется.
     
  11. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.839
    Симпатии:
    651
    Ну, ОК. Хотя для выбора одиночных записей можно сделать и спец. низкоуровневую ф-цию.

    Как выше написали, LIMIT 1 при выборе по id не обязателен.

    Там главное контролировать точное совпадение (хотя бы без учета регистра букв, если речь о сим. id, т.е. слагах). Короче чтобы не было при числовых id таких дублей: /pigs/5-pig
    --- Добавлено ---
    С ведущим нулем тоже могут быть дубли.
     
  12. processsor

    processsor Новичок

    С нами с:
    29 янв 2022
    Сообщения:
    21
    Симпатии:
    0
    Как не надо ? Limit всегда нужен. Если не поставить он и на id будет всю базу сканировать. Проверено. Даже если индексация id есть. То с Limit 1 быстрее .

    Или вы о чем ? fetch - тоже самое , что LIMIT 1 ?

    И мои тесты показывают намного быстрее загрузить в массив и его перебирать чем fetch-ом.

    Для эконимии памяти fetch лучше. для скорости хуже.

    Но если ставить Limit 100 и загружать кусками через fetchall и потом перебирать php это всё равно получается намного быстрее чем просто fetch-ом. и памяти не жрет.

    Ситуации могут быть когда fetchом удобнее. но мне пока не встречались.
     
    #12 processsor, 22 янв 2023
    Последнее редактирование: 22 янв 2023
  13. don.bidon

    don.bidon Активный пользователь

    С нами с:
    28 мар 2021
    Сообщения:
    922
    Симпатии:
    143
    fetch() вынимает одну строку, fetchAll() все, тесты на выборку по уникальному ключу с LIMIT 1 или без писать ЛОМ, кидай готовый код сюда (структура таблицы, скрипт наполнения таблицы, скрипт, демонстрирующий различия), можно погонять и посравнивать результаты.
     
  14. miketomlin

    miketomlin Старожил

    С нами с:
    9 авг 2016
    Сообщения:
    3.839
    Симпатии:
    651
    Не обязателен. Можешь оставить.
    Юник/первичный ключ? Когда-то специально спрашивал у спецов по БД. Сказали, что не обязателен. (Если бы влияло на скорость, так бы не сказали.)

    Не :)

    То что PDOSt::fetchAll «жрет» (неэффективно расходует) память, достаточно известный факт. Вполне можно не использовать без необходимости.

    Насчет «намного» даже для большого цикла с fetch не уверен. В мускулае точно fetch в цикле вполне сравним с fetch_all'ом. И вообще тебя никто не отговаривает использовать FetchAll для цикла, несмотря на расход памяти.
     
    #14 miketomlin, 22 янв 2023
    Последнее редактирование: 22 янв 2023
  15. processsor

    processsor Новичок

    С нами с:
    29 янв 2022
    Сообщения:
    21
    Симпатии:
    0
    Проверил на php 8.1 и mariadb 10.5.

    10000 запросов. с Limit 1 таки чутка дольше . т.е. поиск по primary index без limit 1 - быстрее.

    Но в обычной работе это не заметно. 10000 запросов за раз у меня не бывает.

    Когдато давно тестировал. было наоборот.
     
  16. don.bidon

    don.bidon Активный пользователь

    С нами с:
    28 мар 2021
    Сообщения:
    922
    Симпатии:
    143
    надо бенчить как по PK, так и по UK, набивать UK рандомом, доставать данные из 3-го поля, набитого рандомом одинаковой длины и так, чтобы запросы к БД самой БД не кэшировались. набрось код, хз, что ты набенчил )
     
  17. processsor

    processsor Новичок

    С нами с:
    29 янв 2022
    Сообщения:
    21
    Симпатии:
    0
    Упс.

    Затестил fetchall vs fetch . fetch по 10000 строкам оказался в 10 раз быстрее fetchall. Ну тогда беру свои слова назад )))
    Тесты совсем не точные, но примерно показывают что надо. Кэширование убрал с помощью NOW() .

    1 тест . 100 раз по 100 строк. просто складывается id

    Код (Text):
    1.      
    2. $query = "SELECT *,NOW() FROM posts LIMIT 100 OFFSET :of";
    3. $sth = $this->db->prepare( $query );
    4. $offset = 100;
    5. for ( $q = 0 ; $q<100 ; $q++ ){
    6.        $sth->bindValue( ':of' , $offset, PDO::PARAM_INT );
    7.        $sth->execute();
    8.        $rez = $sth->fetchAll( PDO::FETCH_ASSOC );
    9.        foreach ( $rez as $r ){
    10.             $w += $r['id'];
    11.         }
    12.         $offset += 100;
    13. }

    2 тест. 10000 строк складывает id .

    Код (Text):
    1.  
    2. $query="SELECT *,NOW() FROM posts LIMIT 10000";
    3. $sth=$this->db->prepare( $query );
    4. $sth->execute();
    5. for ($q=0; $q<10000; $q++){
    6.       $rez = $sth->fetch(PDO::FETCH_ASSOC );
    7.       $w+=$rez['id'];
    8. }

    Не зря тему начал :) чтото узнал