Commit c59d0ee0 authored by Aurel's avatar Aurel

tell mysql to use index only when all column in index are used in query

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@13135 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent eca2b1ce
...@@ -1690,10 +1690,10 @@ class Catalog( Folder, ...@@ -1690,10 +1690,10 @@ class Catalog( Folder,
Return the list of scriptable keys. Return the list of scriptable keys.
""" """
return self.sql_catalog_scriptable_keys return self.sql_catalog_scriptable_keys
def getTableIndex(self, table): def getTableIndex(self, table):
""" """
Return a map between columns and possible index for a given table Return a map between index and column for a given table
""" """
def _getTableIndex(table): def _getTableIndex(table):
table_index = {} table_index = {}
...@@ -1702,51 +1702,50 @@ class Catalog( Folder, ...@@ -1702,51 +1702,50 @@ class Catalog( Folder,
return {} return {}
index = list(method(table=table)) index = list(method(table=table))
for line in index: for line in index:
if table_index.has_key(line.COLUMN_NAME): if table_index.has_key(line.KEY_NAME):
table_index[line.COLUMN_NAME].append(line.KEY_NAME) table_index[line.KEY_NAME].append(line.COLUMN_NAME)
else: else:
table_index[line.COLUMN_NAME] = [line.KEY_NAME,] table_index[line.KEY_NAME] = [line.COLUMN_NAME,]
LOG("SQLCatalog.getTableIndex", ERROR, "index = %s for table = %s" \ LOG("SQLCatalog.getTableIndex", INFO, "index = %s for table = %s" \
%(table_index, table)) %(table_index, table))
return table_index return table_index
return CachingMethod(_getTableIndex, id='SQLCatalog.getTableIndex', \ return CachingMethod(_getTableIndex, id='SQLCatalog.getTableIndex', \
cache_factory='erp5_core_long')(table=table) cache_factory='erp5_core_long')(table=table)
def getIndex(self, table, column_list): def getIndex(self, table, column_list, all_column_list):
""" """
Return possible index for a column list in a given table Return possible index for a column list in a given table
""" """
def _getIndex(table, column_list): def _getIndex(table, column_list, all_column_list):
index_dict = self.getTableIndex(table) index_dict = self.getTableIndex(table)
if isinstance(column_list, str): if isinstance(column_list, str):
column_list = [column_list,] column_list = [column_list,]
index_column = [] # Get possible that can be used
possible_index = {} possible_index = []
# Get possible index for index in index_dict.keys():
for column in column_list: index_columns = index_dict[index]
if index_dict.has_key(column): for column in index_columns:
for index in index_dict[column]: if column in column_list:
if not possible_index.has_key(index): if index not in possible_index:
possible_index[index] = [column,] possible_index.append(index)
else: if len(possible_index) == 0:
possible_index[index].append(column) return []
# Return an index list that cover the maximum of rows # Get the most suitable index
max_column_len = 0 for index in possible_index:
best_index = [] # Make sure all column in index are used by the query
for index in possible_index.keys(): index_column = index_dict[index]
column_list = possible_index[index] for column in index_column:
column_list_length = len(column_list) if column in column_list or column in all_column_list:
if column_list_length > max_column_len: continue
best_index = [index,] else:
max_column_len = column_list_length possible_index.remove(index)
elif column_list_length == max_column_len: LOG("SQLCatalog.getIndex", INFO, "index = %s for table %s and columns %s" \
best_index.append(index) %(possible_index, table, column_list))
LOG("SQLCatalog.getIndex", ERROR, "best_index = %s for table %s and columns %s" \ return possible_index
%(best_index, table, column_list))
return best_index
return CachingMethod(_getIndex, id='SQLCatalog.getIndex', cache_factory='erp5_core_long')\ return CachingMethod(_getIndex, id='SQLCatalog.getIndex', cache_factory='erp5_core_long')\
(table=table, column_list=column_list) (table=table, column_list=column_list, all_column_list=all_column_list)
def buildSQLQuery(self, query_table='catalog', REQUEST=None, def buildSQLQuery(self, query_table='catalog', REQUEST=None,
ignore_empty_string=1, query=None, stat__=0, **kw): ignore_empty_string=1, query=None, stat__=0, **kw):
...@@ -2068,7 +2067,6 @@ class Catalog( Folder, ...@@ -2068,7 +2067,6 @@ class Catalog( Folder,
if len(sort_key_list) > 0: if len(sort_key_list) > 0:
index_from_table = {} index_from_table = {}
# first group columns from a same table # first group columns from a same table
LOG("SQLCatalog.buildSQLQuery", ERROR, "sort_key = %s" %sort_key)
for key in sort_key_list: for key in sort_key_list:
try: try:
related_table, column = key.split('.') related_table, column = key.split('.')
...@@ -2087,7 +2085,7 @@ class Catalog( Folder, ...@@ -2087,7 +2085,7 @@ class Catalog( Folder,
index_from_table[table].append(column) index_from_table[table].append(column)
# second ask index # second ask index
for table in index_from_table.keys(): for table in index_from_table.keys():
available_index_list = self.getIndex(table, index_from_table[table]) available_index_list = self.getIndex(table, index_from_table[table], key_list)
if len(available_index_list) > 0: if len(available_index_list) > 0:
# tell mysql to use these index # tell mysql to use these index
table = from_table_dict.pop(related_table) table = from_table_dict.pop(related_table)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment