MySQL Limits
- joebert
- Sledgehammer


- Joined: Feb 10, 2004
- Posts: 13455
- Loc: Florida
- Status: Offline
I finally got around to the part of my project that needs to do something like this yesterday. I just wanted to make a note of two ways I tried.
Here's the first attempt. It averages 1.6 seconds to generate the page on the test server.
Then there's the second attempt, takes 0.19 seconds on average to generate the page.
In both situations it's generating a page for 15 categories total, a couple are parent categories that include 1-10 sub categories.
I'm thinking about adding two columns to the categories table called "min_id" and "max"id" that line up with the insert_id column on my relations table that I can use with a BETWEEN clause to cut down on the number of rows it needs to scan. I have to work out how to handle updating those indexes though.
Here's the first attempt. It averages 1.6 seconds to generate the page on the test server.
PHP Code: [ Select ]
$result = $db->query('SELECT category_id, label, description FROM ' . CATEGORIES_TABLE . ' WHERE soi = TRUE ORDER BY label ASC', MYSQLI_USE_RESULT);
while($row = $result->fetch_object())
{
$c->categories[] = $row;
}
$result->close();
$sql = $db->prepare('
SELECT wp.label, wp.path, wp.wallpaper_id
FROM ' . CAT_WP_RELATIONS_TABLE . ' rel
LEFT JOIN ' . WALLPAPERS_TABLE . ' wp
ON rel.wallpaper_id = wp.wallpaper_id
WHERE rel.category_id IN ((SELECT category_id FROM ' . CATEGORIES_TABLE . " WHERE ? IN(category_id, parent_id)))
ORDER BY rel.insert_order DESC LIMIT {$config->options->index->new_wallpapers->count}"
);
if(!$sql){$page->messages .= new message($db->error);}
else{$sql->bind_param('s', $c->category_id);}
foreach($c->categories as &$c->category)
{if(!$sql){continue;}
$c->category->url = sprintf($config->options->url->rewrite_mode ? $config->options->url->category_mask : 'index.php?category_id=%1$s&page=%3$s',
$c->category->category_id,
string_utils::htmlentities($c->category->label),
1
);
$c->category_id = $c->category->category_id;
$c->wallpapers = '';
if($sql->execute())
{
$sql->bind_result($c->wallpaper->label, $c->wallpaper->path, $c->wallpaper->wallpaper_id);
while($sql->fetch())
{
while($row = $result->fetch_object())
{
$c->categories[] = $row;
}
$result->close();
$sql = $db->prepare('
SELECT wp.label, wp.path, wp.wallpaper_id
FROM ' . CAT_WP_RELATIONS_TABLE . ' rel
LEFT JOIN ' . WALLPAPERS_TABLE . ' wp
ON rel.wallpaper_id = wp.wallpaper_id
WHERE rel.category_id IN ((SELECT category_id FROM ' . CATEGORIES_TABLE . " WHERE ? IN(category_id, parent_id)))
ORDER BY rel.insert_order DESC LIMIT {$config->options->index->new_wallpapers->count}"
);
if(!$sql){$page->messages .= new message($db->error);}
else{$sql->bind_param('s', $c->category_id);}
foreach($c->categories as &$c->category)
{if(!$sql){continue;}
$c->category->url = sprintf($config->options->url->rewrite_mode ? $config->options->url->category_mask : 'index.php?category_id=%1$s&page=%3$s',
$c->category->category_id,
string_utils::htmlentities($c->category->label),
1
);
$c->category_id = $c->category->category_id;
$c->wallpapers = '';
if($sql->execute())
{
$sql->bind_result($c->wallpaper->label, $c->wallpaper->path, $c->wallpaper->wallpaper_id);
while($sql->fetch())
{
- $result = $db->query('SELECT category_id, label, description FROM ' . CATEGORIES_TABLE . ' WHERE soi = TRUE ORDER BY label ASC', MYSQLI_USE_RESULT);
- while($row = $result->fetch_object())
- {
- $c->categories[] = $row;
- }
- $result->close();
- $sql = $db->prepare('
- SELECT wp.label, wp.path, wp.wallpaper_id
- FROM ' . CAT_WP_RELATIONS_TABLE . ' rel
- LEFT JOIN ' . WALLPAPERS_TABLE . ' wp
- ON rel.wallpaper_id = wp.wallpaper_id
- WHERE rel.category_id IN ((SELECT category_id FROM ' . CATEGORIES_TABLE . " WHERE ? IN(category_id, parent_id)))
- ORDER BY rel.insert_order DESC LIMIT {$config->options->index->new_wallpapers->count}"
- );
- if(!$sql){$page->messages .= new message($db->error);}
- else{$sql->bind_param('s', $c->category_id);}
- foreach($c->categories as &$c->category)
- {if(!$sql){continue;}
- $c->category->url = sprintf($config->options->url->rewrite_mode ? $config->options->url->category_mask : 'index.php?category_id=%1$s&page=%3$s',
- $c->category->category_id,
- string_utils::htmlentities($c->category->label),
- 1
- );
- $c->category_id = $c->category->category_id;
- $c->wallpapers = '';
- if($sql->execute())
- {
- $sql->bind_result($c->wallpaper->label, $c->wallpaper->path, $c->wallpaper->wallpaper_id);
- while($sql->fetch())
- {
Then there's the second attempt, takes 0.19 seconds on average to generate the page.
PHP Code: [ Select ]
$c->categories = array();
$result = $db->query('SELECT category_id, label, description FROM ' . CATEGORIES_TABLE . ' WHERE soi = TRUE', MYSQLI_USE_RESULT);
while($row = $result->fetch_object())
{
$row->sub_categories = array($row->category_id => $row->category_id);
$c->categories[$row->category_id] = $row;
}
$result->close();
$result = $db->query('
SELECT category_id, parent_id
FROM ' . CATEGORIES_TABLE . '
WHERE parent_id IN(' . implode(',', array_keys($c->categories)) . ')'
);
while($row = $result->fetch_object())
{
$c->categories[$row->parent_id]->sub_categories[$row->category_id] = $row->category_id;
}
$result->close();
$c->max_subs = 0;
foreach($c->categories as &$c->category)
{
$c->max_subs = max($c->max_subs, count($c->category->sub_categories));
}
foreach($c->categories as &$c->category)
{
$c->category->sub_categories = array_pad($c->category->sub_categories, $c->max_subs, current($c->category->sub_categories));
}
function __sort_cats_label($a, $b){return mb_strtolower($a->label) > mb_strtolower($b->label) ? 1 : -1;}
usort($c->categories, '__sort_cats_label');
$sql = $db->prepare('
SELECT wp.label, wp.path, wp.wallpaper_id
FROM ' . CAT_WP_RELATIONS_TABLE . ' rel
LEFT JOIN ' . WALLPAPERS_TABLE . ' wp
ON rel.wallpaper_id = wp.wallpaper_id
WHERE rel.category_id IN (' . implode(',', array_fill(0, $c->max_subs, '?')) . ")
ORDER BY rel.insert_order DESC LIMIT {$config->options->index->new_wallpapers->count}"
);
if(!$sql){$page->messages .= new message($db->error);}
foreach($c->categories as &$c->category)
{if(!$sql){continue;}
$c->category->url = sprintf($config->options->url->rewrite_mode ? $config->options->url->category_mask : 'index.php?category_id=%1$s&page=%3$s',
$c->category->category_id,
string_utils::htmlentities($c->category->label),
1
);
array_unshift($c->category->sub_categories, str_repeat('i', $c->max_subs));
call_user_func_array(array($sql, 'bind_param'), $c->category->sub_categories);
$c->wallpapers = '';
if($sql->execute())
{
$sql->bind_result($c->wallpaper->label, $c->wallpaper->path, $c->wallpaper->wallpaper_id);
while($sql->fetch())
{
$result = $db->query('SELECT category_id, label, description FROM ' . CATEGORIES_TABLE . ' WHERE soi = TRUE', MYSQLI_USE_RESULT);
while($row = $result->fetch_object())
{
$row->sub_categories = array($row->category_id => $row->category_id);
$c->categories[$row->category_id] = $row;
}
$result->close();
$result = $db->query('
SELECT category_id, parent_id
FROM ' . CATEGORIES_TABLE . '
WHERE parent_id IN(' . implode(',', array_keys($c->categories)) . ')'
);
while($row = $result->fetch_object())
{
$c->categories[$row->parent_id]->sub_categories[$row->category_id] = $row->category_id;
}
$result->close();
$c->max_subs = 0;
foreach($c->categories as &$c->category)
{
$c->max_subs = max($c->max_subs, count($c->category->sub_categories));
}
foreach($c->categories as &$c->category)
{
$c->category->sub_categories = array_pad($c->category->sub_categories, $c->max_subs, current($c->category->sub_categories));
}
function __sort_cats_label($a, $b){return mb_strtolower($a->label) > mb_strtolower($b->label) ? 1 : -1;}
usort($c->categories, '__sort_cats_label');
$sql = $db->prepare('
SELECT wp.label, wp.path, wp.wallpaper_id
FROM ' . CAT_WP_RELATIONS_TABLE . ' rel
LEFT JOIN ' . WALLPAPERS_TABLE . ' wp
ON rel.wallpaper_id = wp.wallpaper_id
WHERE rel.category_id IN (' . implode(',', array_fill(0, $c->max_subs, '?')) . ")
ORDER BY rel.insert_order DESC LIMIT {$config->options->index->new_wallpapers->count}"
);
if(!$sql){$page->messages .= new message($db->error);}
foreach($c->categories as &$c->category)
{if(!$sql){continue;}
$c->category->url = sprintf($config->options->url->rewrite_mode ? $config->options->url->category_mask : 'index.php?category_id=%1$s&page=%3$s',
$c->category->category_id,
string_utils::htmlentities($c->category->label),
1
);
array_unshift($c->category->sub_categories, str_repeat('i', $c->max_subs));
call_user_func_array(array($sql, 'bind_param'), $c->category->sub_categories);
$c->wallpapers = '';
if($sql->execute())
{
$sql->bind_result($c->wallpaper->label, $c->wallpaper->path, $c->wallpaper->wallpaper_id);
while($sql->fetch())
{
- $c->categories = array();
- $result = $db->query('SELECT category_id, label, description FROM ' . CATEGORIES_TABLE . ' WHERE soi = TRUE', MYSQLI_USE_RESULT);
- while($row = $result->fetch_object())
- {
- $row->sub_categories = array($row->category_id => $row->category_id);
- $c->categories[$row->category_id] = $row;
- }
- $result->close();
- $result = $db->query('
- SELECT category_id, parent_id
- FROM ' . CATEGORIES_TABLE . '
- WHERE parent_id IN(' . implode(',', array_keys($c->categories)) . ')'
- );
- while($row = $result->fetch_object())
- {
- $c->categories[$row->parent_id]->sub_categories[$row->category_id] = $row->category_id;
- }
- $result->close();
- $c->max_subs = 0;
- foreach($c->categories as &$c->category)
- {
- $c->max_subs = max($c->max_subs, count($c->category->sub_categories));
- }
- foreach($c->categories as &$c->category)
- {
- $c->category->sub_categories = array_pad($c->category->sub_categories, $c->max_subs, current($c->category->sub_categories));
- }
- function __sort_cats_label($a, $b){return mb_strtolower($a->label) > mb_strtolower($b->label) ? 1 : -1;}
- usort($c->categories, '__sort_cats_label');
- $sql = $db->prepare('
- SELECT wp.label, wp.path, wp.wallpaper_id
- FROM ' . CAT_WP_RELATIONS_TABLE . ' rel
- LEFT JOIN ' . WALLPAPERS_TABLE . ' wp
- ON rel.wallpaper_id = wp.wallpaper_id
- WHERE rel.category_id IN (' . implode(',', array_fill(0, $c->max_subs, '?')) . ")
- ORDER BY rel.insert_order DESC LIMIT {$config->options->index->new_wallpapers->count}"
- );
- if(!$sql){$page->messages .= new message($db->error);}
- foreach($c->categories as &$c->category)
- {if(!$sql){continue;}
- $c->category->url = sprintf($config->options->url->rewrite_mode ? $config->options->url->category_mask : 'index.php?category_id=%1$s&page=%3$s',
- $c->category->category_id,
- string_utils::htmlentities($c->category->label),
- 1
- );
- array_unshift($c->category->sub_categories, str_repeat('i', $c->max_subs));
- call_user_func_array(array($sql, 'bind_param'), $c->category->sub_categories);
- $c->wallpapers = '';
- if($sql->execute())
- {
- $sql->bind_result($c->wallpaper->label, $c->wallpaper->path, $c->wallpaper->wallpaper_id);
- while($sql->fetch())
- {
In both situations it's generating a page for 15 categories total, a couple are parent categories that include 1-10 sub categories.
I'm thinking about adding two columns to the categories table called "min_id" and "max"id" that line up with the insert_id column on my relations table that I can use with a BETWEEN clause to cut down on the number of rows it needs to scan. I have to work out how to handle updating those indexes though.
Strong with this one, the sudo is.
- Anonymous
- Bot


- Joined: 25 Feb 2008
- Posts: ?
- Loc: Ozzuland
- Status: Online
October 21st, 2009, 2:38 am
1, 2
To Reply to this topic you need to LOGIN or REGISTER. It is free.
Post Information
- Total Posts in this topic: 16 posts
- Users browsing this forum: No registered users and 153 guests
- You cannot post new topics in this forum
- You cannot reply to topics in this forum
- You cannot edit your posts in this forum
- You cannot delete your posts in this forum
- You cannot post attachments in this forum
