Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
e8b74f68
Commit
e8b74f68
authored
Oct 11, 2004
by
unknown
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Manual merge with implementation for WL#1724
parent
22ecf1d7
Changes
2
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
282 additions
and
205 deletions
+282
-205
sql/opt_range.cc
sql/opt_range.cc
+38
-17
sql/sql_select.cc
sql/sql_select.cc
+244
-188
No files found.
sql/opt_range.cc
View file @
e8b74f68
...
...
@@ -1672,8 +1672,9 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
if
(
!
head
->
used_keys
.
is_clear_all
())
{
int
key_for_use
=
find_shortest_key
(
head
,
&
head
->
used_keys
);
double
key_read_time
=
get_index_only_read_time
(
&
param
,
records
,
key_for_use
);
double
key_read_time
=
(
get_index_only_read_time
(
&
param
,
records
,
key_for_use
)
+
(
double
)
records
/
TIME_FOR_COMPARE
);
DBUG_PRINT
(
"info"
,
(
"'all'+'using index' scan will be using key %d, "
"read time %g"
,
key_for_use
,
key_read_time
));
if
(
key_read_time
<
read_time
)
...
...
@@ -2176,6 +2177,12 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge,
assumed that each time we read the next key from the index, the handler
performs a random seek, thus the cost is proportional to the number of
blocks read.
TODO:
Move this to handler->read_time() by adding a flag 'index-only-read' to
this call. The reason for doing this is that the current function doesn't
handle the case when the row is stored in the b-tree (like in innodb
clustered index)
*/
inline
double
get_index_only_read_time
(
const
PARAM
*
param
,
ha_rows
records
,
...
...
@@ -2190,6 +2197,7 @@ inline double get_index_only_read_time(const PARAM* param, ha_rows records,
return
read_time
;
}
typedef
struct
st_ror_scan_info
{
uint
idx
;
/* # of used key in param->keys */
...
...
@@ -3056,22 +3064,24 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
tree
->
n_ror_scans
++
;
tree
->
ror_scans_map
.
set_bit
(
idx
);
}
double
cpu_cost
=
(
double
)
found_records
/
TIME_FOR_COMPARE
;
if
(
found_records
!=
HA_POS_ERROR
&&
found_records
>
2
&&
read_index_only
&&
(
param
->
table
->
file
->
index_flags
(
keynr
,
param
->
max_key_part
,
1
)
&
HA_KEYREAD_ONLY
)
&&
!
(
pk_is_clustered
&&
keynr
==
param
->
table
->
primary_key
))
/* We can resolve this by only reading through this key. */
found_read_time
=
get_index_only_read_time
(
param
,
found_records
,
keynr
);
found_read_time
=
get_index_only_read_time
(
param
,
found_records
,
keynr
)
+
cpu_cost
;
else
/*
cost(read_through_index) = cost(disk_io) + cost(row_in_range_checks)
The row_in_range check is in QUICK_RANGE_SELECT::cmp_next function.
*/
found_read_time
=
(
param
->
table
->
file
->
read_time
(
keynr
,
param
->
range_count
,
found_records
)
+
(
double
)
found_records
/
TIME_FOR_COMPARE
)
;
found_read_time
=
param
->
table
->
file
->
read_time
(
keynr
,
param
->
range_count
,
found_records
)
+
cpu_cost
;
DBUG_PRINT
(
"info"
,(
"read_time: %g found_read_time: %g"
,
read_time
,
found_read_time
));
...
...
@@ -3424,6 +3434,7 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
{
uint
maybe_null
=
(
uint
)
field
->
real_maybe_null
(),
copies
;
uint
field_length
=
field
->
pack_length
()
+
maybe_null
;
bool
optimize_range
;
SEL_ARG
*
tree
;
char
*
str
,
*
str2
;
DBUG_ENTER
(
"get_mm_leaf"
);
...
...
@@ -3454,6 +3465,9 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
((
Field_str
*
)
field
)
->
charset
()
!=
conf_func
->
compare_collation
())
DBUG_RETURN
(
0
);
optimize_range
=
field
->
optimize_range
(
param
->
real_keynr
[
key_part
->
key
],
key_part
->
part
);
if
(
type
==
Item_func
::
LIKE_FUNC
)
{
bool
like_error
;
...
...
@@ -3461,8 +3475,7 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
String
tmp
(
buff1
,
sizeof
(
buff1
),
value
->
collation
.
collation
),
*
res
;
uint
length
,
offset
,
min_length
,
max_length
;
if
(
!
field
->
optimize_range
(
param
->
real_keynr
[
key_part
->
key
],
key_part
->
part
))
if
(
!
optimize_range
)
DBUG_RETURN
(
0
);
// Can't optimize this
if
(
!
(
res
=
value
->
val_str
(
&
tmp
)))
DBUG_RETURN
(
&
null_element
);
...
...
@@ -3527,8 +3540,7 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
DBUG_RETURN
(
new
SEL_ARG
(
field
,
min_str
,
max_str
));
}
if
(
!
field
->
optimize_range
(
param
->
real_keynr
[
key_part
->
key
],
key_part
->
part
)
&&
if
(
!
optimize_range
&&
type
!=
Item_func
::
EQ_FUNC
&&
type
!=
Item_func
::
EQUAL_FUNC
)
DBUG_RETURN
(
0
);
// Can't optimize this
...
...
@@ -3542,7 +3554,7 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part,
field
->
cmp_type
()
!=
value
->
result_type
())
DBUG_RETURN
(
0
);
if
(
value
->
save_in_field
(
field
,
1
)
<
0
)
if
(
value
->
save_in_field
_no_warnings
(
field
,
1
)
<
0
)
{
/* This happens when we try to insert a NULL field in a not null column */
DBUG_RETURN
(
&
null_element
);
// cmp with NULL is never TRUE
...
...
@@ -3736,14 +3748,15 @@ tree_and(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
if
(
*
key2
&&
!
(
*
key2
)
->
simple_key
())
flag
|=
CLONE_KEY2_MAYBE
;
*
key1
=
key_and
(
*
key1
,
*
key2
,
flag
);
if
((
*
key1
)
->
type
==
SEL_ARG
::
IMPOSSIBLE
)
if
(
*
key1
&&
(
*
key1
)
->
type
==
SEL_ARG
::
IMPOSSIBLE
)
{
tree1
->
type
=
SEL_TREE
::
IMPOSSIBLE
;
DBUG_RETURN
(
tree1
);
}
result_keys
.
set_bit
(
key1
-
tree1
->
keys
);
#ifdef EXTRA_DEBUG
(
*
key1
)
->
test_use_count
(
*
key1
);
if
(
*
key1
)
(
*
key1
)
->
test_use_count
(
*
key1
);
#endif
}
}
...
...
@@ -3974,6 +3987,13 @@ key_and(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag)
return
key1
;
}
if
((
key1
->
min_flag
|
key2
->
min_flag
)
&
GEOM_FLAG
)
{
key1
->
free_tree
();
key2
->
free_tree
();
return
0
;
// Can't optimize this
}
key1
->
use_count
--
;
key2
->
use_count
--
;
SEL_ARG
*
e1
=
key1
->
first
(),
*
e2
=
key2
->
first
(),
*
new_tree
=
0
;
...
...
@@ -4056,7 +4076,8 @@ key_or(SEL_ARG *key1,SEL_ARG *key2)
key1
->
use_count
--
;
key2
->
use_count
--
;
if
(
key1
->
part
!=
key2
->
part
)
if
(
key1
->
part
!=
key2
->
part
||
(
key1
->
min_flag
|
key2
->
min_flag
)
&
GEOM_FLAG
)
{
key1
->
free_tree
();
key2
->
free_tree
();
...
...
@@ -4716,7 +4737,7 @@ void SEL_ARG::test_use_count(SEL_ARG *root)
ulong
count
=
count_key_part_usage
(
root
,
pos
->
next_key_part
);
if
(
count
>
pos
->
next_key_part
->
use_count
)
{
sql_print_error
(
"Note: Use_count: Wrong count for key at %lx, %lu should be %lu"
,
sql_print_error
(
"Note: Use_count: Wrong count for key at
0x
%lx, %lu should be %lu"
,
pos
,
pos
->
next_key_part
->
use_count
,
count
);
return
;
}
...
...
@@ -4724,7 +4745,7 @@ void SEL_ARG::test_use_count(SEL_ARG *root)
}
}
if
(
e_count
!=
elements
)
sql_print_error
(
"Warning: Wrong use count: %u (should be %u) for tree at %lx"
,
sql_print_error
(
"Warning: Wrong use count: %u (should be %u) for tree at
0x
%lx"
,
e_count
,
elements
,
(
gptr
)
this
);
}
...
...
sql/sql_select.cc
View file @
e8b74f68
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment