对不起这个问题。我不是一个优秀的程序员
Everything使用少量菜单项执行得很好。但有14K菜单项。我坚持这个查询。当我尝试访问
时会发生这种情况 administrator/index.php?option=com_modules&view=module&layout=edit&id=97
有没有办法改变查询??
查询
SELECT a.id AS value,
a.title AS text,
a.alias,
a.level,
a.menutype,
a.type,
a.template_style_id,
a.checked_out
FROM gjb0e_menu AS a
LEFT JOIN `gjb0e_menu` AS b
ON a.lft > b.lft
AND a.rgt < b.rgt
WHERE a.published != -2
GROUP BY a.id,
a.title,
a.alias,
a.level,
a.menutype,
a.type,
a.template_style_id,
a.checked_out,
a.lft
ORDER BY a.lft ASC
Php代码
require_once JPATH_ADMINISTRATOR . '/components/com_menus/helpers/menus.php';
$menuTypes = MenusHelper::getMenuLinks();
<ul class="treeselect">
<?php foreach ($menuTypes as &$type) : ?>
<?php if (count($type->links)) : ?>
<?php $prevlevel = 0; ?>
<li>
<div class="treeselect-item pull-left">
<label class="pull-left nav-header"><?php echo $type->title; ?></label></div>
<?php foreach ($type->links as $i => $link) : ?>
<?php
if ($prevlevel < $link->level)
{
echo '<ul class="treeselect-sub">';
} elseif ($prevlevel > $link->level)
{
echo str_repeat('</li></ul>', $prevlevel - $link->level);
} else {
echo '</li>';
}
$selected = 0;
if ($this->item->assignment == 0)
{
$selected = 1;
} elseif ($this->item->assignment < 0)
{
$selected = in_array(-$link->value, $this->item->assigned);
} elseif ($this->item->assignment > 0)
{
$selected = in_array($link->value, $this->item->assigned);
}
?>
<li>
<div class="treeselect-item pull-left">
<input type="checkbox" class="pull-left" name="jform[assigned][]" id="<?php echo $id . $link->value; ?>" value="<?php echo (int) $link->value; ?>"<?php echo $selected ? ' checked="checked"' : ''; ?> />
<label for="<?php echo $id . $link->value; ?>" class="pull-left"><?php echo $link->text; ?> <span class="small"><?php echo JText::sprintf('JGLOBAL_LIST_ALIAS', $this->escape($link->alias));?></span></label>
</div>
<?php
if (!isset($type->links[$i + 1]))
{
echo str_repeat('</li></ul>', $link->level);
}
$prevlevel = $link->level;
?>
<?php endforeach; ?>
</li>
<?php endif; ?>
<?php endforeach; ?>
</ul>
这是创建查询的函数。
public static function getMenuLinks($menuType = null, $parentId = 0, $mode = 0, $published = array(), $languages = array())
{
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('a.id AS value, a.title AS text, a.alias, a.level, a.menutype, a.type, a.template_style_id, a.checked_out')
->from('#__menu AS a')
->join('LEFT', $db->quoteName('#__menu') . ' AS b ON a.lft > b.lft AND a.rgt < b.rgt');
// Filter by the type
if ($menuType)
{
$query->where('(a.menutype = ' . $db->quote($menuType) . ' OR a.parent_id = 0)');
}
if ($parentId)
{
if ($mode == 2)
{
// Prevent the parent and children from showing.
$query->join('LEFT', '#__menu AS p ON p.id = ' . (int) $parentId)
->where('(a.lft <= p.lft OR a.rgt >= p.rgt)');
}
}
if (!empty($languages))
{
if (is_array($languages))
{
$languages = '(' . implode(',', array_map(array($db, 'quote'), $languages)) . ')';
}
$query->where('a.language IN ' . $languages);
}
if (!empty($published))
{
if (is_array($published))
{
$published = '(' . implode(',', $published) . ')';
}
$query->where('a.published IN ' . $published);
}
$query->where('a.published != -2')
->group('a.id, a.title, a.alias, a.level, a.menutype, a.type, a.template_style_id, a.checked_out, a.lft')
->order('a.lft ASC');
// Get the options.
$db->setQuery($query);
try
{
$links = $db->loadObjectList();
}
catch (RuntimeException $e)
{
JError::raiseWarning(500, $e->getMessage());
return false;
}
if (empty($menuType))
{
// If the menutype is empty, group the items by menutype.
$query->clear()
->select('*')
->from('#__menu_types')
->where('menutype <> ' . $db->quote(''))
->order('title, menutype');
$db->setQuery($query);
try
{
$menuTypes = $db->loadObjectList();
}
catch (RuntimeException $e)
{
JError::raiseWarning(500, $e->getMessage());
return false;
}
// Create a reverse lookup and aggregate the links.
$rlu = array();
foreach ($menuTypes as &$type)
{
$rlu[$type->menutype] = & $type;
$type->links = array();
}
// Loop through the list of menu links.
foreach ($links as &$link)
{
if (isset($rlu[$link->menutype]))
{
$rlu[$link->menutype]->links[] = & $link;
// Cleanup garbage.
unset($link->menutype);
}
}
return $menuTypes;
}
else
{
return $links;
}
答案 0 :(得分:1)
您只需删除联接即可。我非常确定连接对您的查询完全没有影响,并且会更快。您可以尝试使用和不使用连接直接在数据库中运行查询,以验证结果是否相同。
我不确定这个联接的目的是什么,但我想这是程序员试图实现的某些功能的残余,但是这种情况有所不同或者掉线,留下了无用的连接。
这种分层表的结构是这样的,以防止这种类型的连接。你有一个lft和一个rgt值,并且在lft和rgt之间的任何项目都是一个子项目。此外,您还有一个级别值,告诉您树中的值有多深。因此,要选择项目的所有子项,您可以执行以下操作:
select * where lft>item.lft and rgt>item.rgt
要仅选择项目的直接后代,请执行
select * where lft>item.lft and rgt>item.rgt and level=item.level+1
数据库中的结构有点难以维护,需要特殊功能来更新数据,但搜索和提取数据的速度很快。
所以,你的getMenuLinks() - 函数应该像
一样开始public static function getMenuLinks($menuType = null, $parentId = 0,
$mode = 0, $published = array(), $languages = array())
{
$db = JFactory::getDbo();
$query = $db->getQuery(true)
->select('a.id AS value, a.title AS text, a.alias, a.level,
a.menutype, a.type, a.template_style_id, a.checked_out')
->from('#__menu AS a');
// Filter by the type
if ($menuType)
...