让Doctrine使用MySQL“FORCE INDEX”

时间:2009-12-04 22:57:49

标签: php mysql doctrine

我在Doctrine的DQL中有一个查询需要能够使用MySQL的“FORCE INDEX”功能,以便大大缩短查询时间。以下是查询在纯SQL中的基本外观:

SELECT id FROM items FORCE INDEX (best_selling_idx)
WHERE price = ... (etc)
LIMIT 200;

我假设我必须扩展一些Doctrine组件才能用DQL执行此操作(或者有没有办法将任意SQL注入Doctrin的查询之一?)。有人有什么想法吗?

谢谢!

4 个答案:

答案 0 :(得分:6)

我在网上找到了很少有用的Doctrine_RawSql示例,所以这就是我最终要创建的查询。

$q = new Doctrine_RawSql();
$q->select('{b.id}, {b.description}, {c.description}')
  ->from('table1 b FORCE INDEX(best_selling_idx) INNER JOIN table2 c ON b.c_id = c.id')
  ->addComponent('b', 'Table1 b')
  ->addComponent('c', 'b.Table2 c');

答案 1 :(得分:3)

如果您不喜欢本机SQL,则可以使用以下修补程序。 https://gist.github.com/arnaud-lb/2704404

此补丁建议只创建一个自定义Walker并按如下所示进行设置

$query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, 'UseIndexWalker');
$query->setHint(UseIndexWalker::HINT_USE_INDEX, 'some_index_name');

答案 2 :(得分:1)

the Native SQL part of the Doctrine documentation。您应该能够使用RawSql来完成此任务。

答案 3 :(得分:1)

我创建了一个DocTrine SqlWalker扩展,以在MySql之上使用DQL应用USE INDEX和FORCE INDEX提示。与createQuery和createQueryBuilder一起使用。您可以为每个DQL表别名设置不同的索引提示。

use Ggergo\SqlIndexHintBundle\SqlIndexWalker;
...
$query = ...;
$query->setHint(Query::HINT_CUSTOM_OUTPUT_WALKER, SqlIndexWalker::class);
$query->setHint(SqlIndexWalker::HINT_INDEX, [
    'your_dql_table_alias'           => 'FORCE INDEX FOR JOIN (your_composite_index) FORCE INDEX FOR ORDER BY (PRIMARY)',
    'your_another_dql_table_alias'   => 'FORCE INDEX (PRIMARY)',
    ...
]);

https://github.com/ggergo/SqlIndexHintBundle