массивный убийца order by rand()

Обсуждение документации. Переводы Cookbook и авторские рецепты.
Ответить
gax
Сообщения: 30
Зарегистрирован: 2014.08.21, 17:12

массивный убийца order by rand()

Сообщение gax » 2015.02.10, 09:50

Может кому-нибудь пригодится =)

Код: Выделить всё

        
        $model = Product::model()->findAll();

        foreach($model as $one) {

            $item = array(

                'id' => $one->id,
                'img' => $one->img,
                'title' => $one->title,
                'discount' => $one->discount,
                'price' => $one->price);
            array_push($this->items, $item);
        }

        shuffle($this->items); //перемешали

        $output = array_slice($this->items, 0, 8); // а это вместо limit 8

        $this->render('_random', array('items' => $output));
 
В виде обращаться как к массиву естественно.

Аватара пользователя
samdark
Администратор
Сообщения: 8552
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: массивный убийца order by rand()

Сообщение samdark » 2015.02.10, 11:16

Я бы добавил limit и offset к самому запросы. Выгребать абсолютно все данные накладно.

Аватара пользователя
SiZE
Сообщения: 2423
Зарегистрирован: 2011.09.21, 12:39
Откуда: Perm
Контактная информация:

Re: массивный убийца order by rand()

Сообщение SiZE » 2015.02.10, 11:41

Для чего этот кусочек треша?

Аватара пользователя
Insolita
Сообщения: 788
Зарегистрирован: 2011.06.06, 01:39
Контактная информация:

Re: массивный убийца order by rand()

Сообщение Insolita » 2015.02.10, 12:09

gax писал(а):Может кому-нибудь пригодится =)

В виде обращаться как к массиву естественно.
Жёстко... если так важна экономия, то

Код: Выделить всё

        
        $model = Product::model()->findAll(['select'=>'id']); 
        $ids=[];
        foreach($model as $one) {
            array_push($ids, $one->id);
        }

        shuffle($ids); //перемешали

        $output = array_slice($ids, 0, 8); // а это вместо limit 8
        $model = Product::model()->findAll(['condition'=>['id'=>$ids]]);
 
Вариант2

Код: Выделить всё

        
        $ids = Product::model()->findAll(['select'=>'id','orderBy'=>'RAND()','limit'=>8]); // И лучше через ДАО
        $model = Product::model()->findAll(['condition'=>['id'=>$ids]]);
 
С синтаксисом условий могла напутать после двойки...но думаю суть понятна

gax
Сообщения: 30
Зарегистрирован: 2014.08.21, 17:12

Re: массивный убийца order by rand()

Сообщение gax » 2015.02.11, 07:35

Ну кароч у меня магазин и запросы с rand() обрабатываются неприемлимо долго, учитывая что виджет с рендомными товарами у меня почти на каждой странице. Мультиязычность привязана к моделям, поэтому ДАО я использовать не могу, у меня был вариант попробовать сложный sql запрос составить, но я смутно понимаю их логику, а так норм =)
И я всегда считал что один толстый запрос к бд будет есть меньше ресурсов чем два небольших запроса. Я что был не прав? =(

Аватара пользователя
Insolita
Сообщения: 788
Зарегистрирован: 2011.06.06, 01:39
Контактная информация:

Re: массивный убийца order by rand()

Сообщение Insolita » 2015.02.11, 08:04

gax писал(а): Мультиязычность привязана к моделям, поэтому ДАО я использовать не могу,
Для выборки id мультиязычность для ДАО не помеха

Код: Выделить всё

И я всегда считал что один толстый запрос к бд будет есть меньше ресурсов чем два небольших запроса. Я что был не прав? =( 
бывают и исключения. к тому же можно и в один запрос объединить правда с через AR сложновато http://rmcreative.ru/blog/post/optimiza ... er-by-rand http://hudson.su/2010/09/16/mysql-optim ... r-by-rand/

Ответить