Better indexing for string properties to support path-based lookups

- Normal prefix-index has been shortened to 32 chars (from 64)
 - Added a fully indexed 'string_end' column of 16 characters
 - iBatis queries are optimized to pull short strings from the index
 - Long paths and NodeRefs are well-indexed using this approach


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@15833 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2009-08-20 13:03:29 +00:00
parent f1e5670836
commit 33cb2a4d75
5 changed files with 91 additions and 41 deletions

View File

@@ -45,8 +45,10 @@ CREATE TABLE alf_prop_double_value
CREATE TABLE alf_prop_string_value CREATE TABLE alf_prop_string_value
( (
id BIGINT NOT NULL AUTO_INCREMENT, id BIGINT NOT NULL AUTO_INCREMENT,
string_value text NOT NULL, string_value TEXT NOT NULL,
INDEX idx_alf_prop_str_val (string_value(64)), string_end VARCHAR(16) NOT NULL,
INDEX idx_alf_prop_str_start (string_value(32)),
INDEX idx_alf_prop_str_end (string_end),
PRIMARY KEY (id) PRIMARY KEY (id)
) ENGINE=InnoDB; ) ENGINE=InnoDB;

View File

@@ -44,6 +44,7 @@
<resultMap id="result.PropertyStringValue" class="PropertyStringValue"> <resultMap id="result.PropertyStringValue" class="PropertyStringValue">
<result property="id" column="id" jdbcType="BIGINT" javaType="java.lang.Long"/> <result property="id" column="id" jdbcType="BIGINT" javaType="java.lang.Long"/>
<result property="stringValue" column="string_value" jdbcType="VARCHAR" javaType="java.lang.String"/> <result property="stringValue" column="string_value" jdbcType="VARCHAR" javaType="java.lang.String"/>
<result property="stringEnd" column="string_end" jdbcType="VARCHAR" javaType="java.lang.String"/>
</resultMap> </resultMap>
<resultMap id="result.PropertyDoubleValue" class="PropertyDoubleValue"> <resultMap id="result.PropertyDoubleValue" class="PropertyDoubleValue">
<result property="id" column="id" jdbcType="BIGINT" javaType="java.lang.Long"/> <result property="id" column="id" jdbcType="BIGINT" javaType="java.lang.Long"/>
@@ -91,8 +92,8 @@
</sql> </sql>
<sql id="insert.PropertyStringValue.AutoIncrement"> <sql id="insert.PropertyStringValue.AutoIncrement">
insert into alf_prop_string_value (string_value) insert into alf_prop_string_value (string_value, string_end)
values (#stringValue#) values (#stringValue#, #stringEnd#)
</sql> </sql>
<sql id="insert.PropertyDoubleValue.AutoIncrement"> <sql id="insert.PropertyDoubleValue.AutoIncrement">
@@ -170,23 +171,41 @@
</select> </select>
<!-- Get a property string value by ID --> <!-- Get a property string value by ID -->
<select id="select.PropertyStringValueByID" parameterClass="PropertyStringValue" resultMap="result.PropertyStringValue"> <select id="select.PropertyStringValueByID" parameterClass="PropertyStringValue" resultClass="string">
select select
* string_value
from from
alf_prop_string_value alf_prop_string_value
where where
id = #id# id = #id#
</select> </select>
<!-- Get the property string value by value --> <!-- Get the property string value by value.
Short strings are be pulled back from the index on the 'string_end' column
-->
<select id="select.PropertyStringValueByValue" parameterClass="PropertyStringValue" resultMap="result.PropertyStringValue"> <select id="select.PropertyStringValueByValue" parameterClass="PropertyStringValue" resultMap="result.PropertyStringValue">
select select
* id,
<dynamic>
<!-- Pulling back the string from the string_end column (if possible) more efficient -->
<isEqual property="stringEnd" compareProperty="stringValue">
string_end as string_value,
string_end
</isEqual>
<isNotEqual property="stringEnd" compareProperty="stringValue">
string_value,
string_end
</isNotEqual>
</dynamic>
from from
alf_prop_string_value alf_prop_string_value
where where
string_value = #stringValue# string_end = #stringEnd#
<dynamic>
<isNotEqual property="stringEnd" compareProperty="stringValue">
and string_value = #stringValue#
</isNotEqual>
</dynamic>
</select> </select>
<!-- Get a property double value by ID --> <!-- Get a property double value by ID -->

View File

@@ -423,18 +423,6 @@ public abstract class AbstractPropertyValueDAOImpl implements PropertyValueDAO
*/ */
private class PropertyStringValueCallbackDAO extends EntityLookupCallbackDAOAdaptor<Long, String, Pair<String, Long>> private class PropertyStringValueCallbackDAO extends EntityLookupCallbackDAOAdaptor<Long, String, Pair<String, Long>>
{ {
private final Pair<Long, String> convertEntityToPair(PropertyStringValueEntity entity)
{
if (entity == null)
{
return null;
}
else
{
return entity.getEntityPair();
}
}
public Pair<String, Long> getValueKey(String value) public Pair<String, Long> getValueKey(String value)
{ {
return CrcHelper.getStringCrcPair(value, 128, true, true); return CrcHelper.getStringCrcPair(value, 128, true, true);
@@ -442,26 +430,40 @@ public abstract class AbstractPropertyValueDAOImpl implements PropertyValueDAO
public Pair<Long, String> createValue(String value) public Pair<Long, String> createValue(String value)
{ {
PropertyStringValueEntity entity = createStringValue(value); Long key = createStringValue(value);
return convertEntityToPair(entity); return new Pair<Long, String>(key, value);
} }
public Pair<Long, String> findByKey(Long key) public Pair<Long, String> findByKey(Long key)
{ {
PropertyStringValueEntity entity = findStringValueById(key); String value = findStringValueById(key);
return convertEntityToPair(entity); if (value == null)
{
return null;
}
else
{
return new Pair<Long, String>(key, value);
}
} }
public Pair<Long, String> findByValue(String value) public Pair<Long, String> findByValue(String value)
{ {
PropertyStringValueEntity entity = findStringValueByValue(value); Long key = findStringValueByValue(value);
return convertEntityToPair(entity); if (key == null)
{
return null;
}
else
{
return new Pair<Long, String>(key, value);
}
} }
} }
protected abstract PropertyStringValueEntity findStringValueById(Long id); protected abstract String findStringValueById(Long id);
protected abstract PropertyStringValueEntity findStringValueByValue(String value); protected abstract Long findStringValueByValue(String value);
protected abstract PropertyStringValueEntity createStringValue(String value); protected abstract Long createStringValue(String value);
//================================ //================================
// 'alf_prop_double_value' accessors // 'alf_prop_double_value' accessors

View File

@@ -37,6 +37,7 @@ public class PropertyStringValueEntity
{ {
private Long id; private Long id;
private String stringValue; private String stringValue;
private String stringEnd;
public PropertyStringValueEntity() public PropertyStringValueEntity()
{ {
@@ -81,6 +82,23 @@ public class PropertyStringValueEntity
{ {
return new Pair<Long, String>(id, stringValue); return new Pair<Long, String>(id, stringValue);
} }
/**
* Set the string and string-end values
*/
public void setValue(String value)
{
this.stringValue = value;
int len = stringValue.length();
if (len > 16)
{
stringEnd = stringValue.substring(len - 16);
}
else
{
stringEnd = stringValue;
}
}
public Long getId() public Long getId()
{ {
@@ -101,4 +119,14 @@ public class PropertyStringValueEntity
{ {
this.stringValue = stringValue; this.stringValue = stringValue;
} }
public String getStringEnd()
{
return stringEnd;
}
public void setStringEnd(String stringEnd)
{
this.stringEnd = stringEnd;
}
} }

View File

@@ -157,34 +157,34 @@ public class PropertyValueDAOImpl extends AbstractPropertyValueDAOImpl
//================================ //================================
@Override @Override
protected PropertyStringValueEntity findStringValueById(Long id) protected String findStringValueById(Long id)
{ {
PropertyStringValueEntity entity = new PropertyStringValueEntity(); PropertyStringValueEntity entity = new PropertyStringValueEntity();
entity.setId(id); entity.setId(id);
entity = (PropertyStringValueEntity) template.queryForObject( String value = (String) template.queryForObject(
SELECT_PROPERTY_STRING_VALUE_BY_ID, SELECT_PROPERTY_STRING_VALUE_BY_ID,
entity); entity);
// Done // Done
return entity; return value;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
protected PropertyStringValueEntity findStringValueByValue(String value) protected Long findStringValueByValue(String value)
{ {
PropertyStringValueEntity entity = new PropertyStringValueEntity(); PropertyStringValueEntity entity = new PropertyStringValueEntity();
entity.setStringValue(value); entity.setValue(value);
List<PropertyStringValueEntity> results = (List<PropertyStringValueEntity>) template.queryForList( List<PropertyStringValueEntity> results = (List<PropertyStringValueEntity>) template.queryForList(
SELECT_PROPERTY_STRING_VALUE_BY_VALUE, SELECT_PROPERTY_STRING_VALUE_BY_VALUE,
entity); entity);
// There double be several matches (if the database is case-insensitive), so find the first // There could be several matches (if the database is case-insensitive), so find the first
// value that matches exactly. // value that matches exactly.
for (PropertyStringValueEntity resultEntity : results) for (PropertyStringValueEntity resultEntity : results)
{ {
if (value.equals(resultEntity.getStringValue())) if (value.equals(resultEntity.getStringValue()))
{ {
// Found a match // Found a match
return resultEntity; return resultEntity.getId();
} }
} }
// No real match // No real match
@@ -192,14 +192,13 @@ public class PropertyValueDAOImpl extends AbstractPropertyValueDAOImpl
} }
@Override @Override
protected PropertyStringValueEntity createStringValue(String value) protected Long createStringValue(String value)
{ {
PropertyStringValueEntity entity = new PropertyStringValueEntity(); PropertyStringValueEntity entity = new PropertyStringValueEntity();
entity.setStringValue(value); entity.setValue(value);
Long id = (Long) template.insert(INSERT_PROPERTY_STRING_VALUE, entity); Long id = (Long) template.insert(INSERT_PROPERTY_STRING_VALUE, entity);
entity.setId(id);
// Done // Done
return entity; return id;
} }
//================================ //================================