Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
question about pagination
  • Hello! :) I have one question about pagination.
    $config = array('pagination_url' => Uri::create('category/'.$category),
                                'uri_segment' => 2,
                                'total_items' => 4,
                                'per_page' => 4,
                                'current_page'=>1
    
                );
                Pagination::set_config($config);
    

    If I want to make pagination on page I should to know how many item I have in db ('total_items') and after that pagination can to make pagination code.
    But, excuse me.
    If I should to make pagination on page I should to make two db queries? 1. query -> count;
    2. query -> select items from db
    3. pagination class uses step one and step two. When I make simple query with out pagination class and count function:
    Page rendered in 0.0988s
    When I use count query and pagination class
    I got: Page rendered in 0.2988s or Page rendered in 0.5088s Could you give me an advice how I can to optimize code?
    Whole code:
    $countitem = DB::query('
                                        SELECT
                                            count(itemid)
                                        FROM
                                            items
                                        JOIN
                                            category
                                        ON
                                            categoryurl = "'. $category .'"
                                        AND
                                            categoryid = itemcategoryid
                                        AND
                                            quantity >= 1
                                        ')->execute();
    
                $config = array('pagination_url' => Uri::create('category/'.$category),
                                'uri_segment' => 2,
                                'total_items' => $countitem,
                                'per_page' => 4,
                                'current_page'=>1
    
                );
    
                Pagination::set_config($config);
    
               $dbquery = DB::query('SELECT
                                                    categoryurl,
                                                    categoryname,
                                                    thumbnail,
                                                    itemid,
                                                    itemname,
                                                    newprice
                                                FROM
                                                    category
                                                JOIN
                                                    items
                                                ON
                                                    categoryurl = "'. $category .'"
                                                AND
                                                    categoryid = itemcategoryid
                                                AND
                                                    quantity >=1
                                                JOIN
                                                    photo
                                                ON
                                                    itemid = photoitemid
                                                LIMIT '. Pagination::$per_page .'
                                                    ')->execute()->as_array();
    

    Sure, If I will refresh many time page I got mysql cached results.
  • Or maybe to use Cache class?
    Something like that:
    if(Cache::get('countitem')){
                    $countitem = \Fuel\Core\Cache::get('countitem');
                }else{
                    $countitem = \Fuel\Core\DB::query('
                                        SELECT
                                            count(itemid)
                                        FROM
                                            items
                                        JOIN
                                            category
                                        ON
                                            categoryurl = "'. $category .'"
                                        AND
                                            categoryid = itemcategoryid
                                        AND
                                            quantity >= 1
                                        ')->execute();
                    Cache::set('countitem',$countitem,3600*3);
                }
    $config = array('pagination_url' => Uri::create('category/'.$category),
                                'uri_segment' => 2,
                                'total_items' => $countitem,
                                'per_page' => 4,
                                'current_page'=>1
    
                );
    

    But I will have problems with Cache: Fuel\Core\CacheNotFoundException [ Error ]: not found
    COREPATH/classes/cache/storage/driver.php @ line 298 What now?
  • You will always need to run two queries, one to get the total count, and one to get the records of the current page. First thing I notice is that your two queries are not identical, so that can't be right. Only the select part should be different. Secondly, I don't see an offset, so you're always loading records starting from the first. As to the speed, in general code first, and optimize later. And before you optimize, analyse. Since you haven't got a clue why it is so much slower, why do you think caching will help?
  • Harro Verton wrote on Monday 24th of October 2011:
    You will always need to run two queries, one to get the total count, and one to get the records of the current page. First thing I notice is that your two queries are not identical, so that can't be right. Only the select part should be different. Secondly, I don't see an offset, so you're always loading records starting from the first. As to the speed, in general code first, and optimize later. And before you optimize, analyse. Since you haven't got a clue why it is so much slower, why do you think caching will help?

    Thanks for the answers! Check out please - it is my RAW code:
    http://pastebin.com/bUCHCFau
    Router: 'category/(:id)'=>'products/select/$1', 1.http://abba.com/category/desktops
    category: desktops
    2.http://abba.com/category/desktops/pc
    category: desktops and subcategory:pc
    3.http://abba.com/category/desktops/10
    category: desktops and page number 10
    4.http://abba.com/category/desktops/pc/10
    category: desktops and subcategory:pc and page number 10
    Therefore for 1 and 2 I didn't need an offset, but in 3 and 4 sure I will using offset.
    About caching: I do not know what to answer. :)
    I thought it would be a better solution than to make two request every time.
  • Caching might be a solution, but then again, it might not be. If you have a fast database server with lots of memory, and slow or busy local disks, caching might even slow things down. For me, optimizing an application is an iterative process. You start with the application, which should be coded properly (so any slowness is not due to sloppy coding). You then analyse the application, and make a (lets say) top 5 of speed issues. Optimize those. Then iterate until you're happy. If it turns out it's a query, then adding caching is as simple as encapsulating the query in a Cache::call().
  • Harro Verton wrote on Tuesday 25th of October 2011:
    Caching might be a solution, but then again, it might not be. If you have a fast database server with lots of memory, and slow or busy local disks, caching might even slow things down. For me, optimizing an application is an iterative process. You start with the application, which should be coded properly (so any slowness is not due to sloppy coding). You then analyse the application, and make a (lets say) top 5 of speed issues. Optimize those. Then iterate until you're happy. If it turns out it's a query, then adding caching is as simple as encapsulating the query in a Cache::call().
    Thank you ! :)
  • Harro Verton wrote on Monday 24th of October 2011:
    You will always need to run two queries, one to get the total count, and one to get the records of the current page.

    Not necessarily, you can use:
    SELECT SQL_CALC_FOUND_ROWS * FROM table LIMIT 10 OFFSET 100
    

    That gives you the specific records and the total number of records if there was no limit and offset (and where). Although sometimes using two queries (one for the total number and one for the data) is faster.
  • If your database is properly designed, and the correct indexes are defined, a separate COUNT query is almost always faster. If not, well, then you're doing something wrong... ;)
  • I'm wondering whether I should use DB::query or this: $total = Model_Image::find()->select('id')->where('status', Model_Image::STATUS_ACTIVE)->count(); I like mine better but is there a performance gain? Please advise.
  • Enable the profiler (globally in app/config.php and on your db connection), and compare the SQL generated by this statement with the SQL you would write yourself. Chances are that for simple queries like this, you couldn't come up with a better one.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion