0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00

SERVER-15217 remove unused tests in dbtests/plan_ranking.cpp

Closes #985

Signed-off-by: Jason Rassi <rassi@10gen.com>
This commit is contained in:
Qingyang Chen 2015-06-16 14:28:25 -04:00 committed by Jason Rassi
parent dd560fcda0
commit f9043a51b1

View File

@ -505,217 +505,6 @@ namespace PlanRankingTests {
}
};
/**
* Index intersection solutions can be covered when single-index solutions
* are not. If the single-index solutions need to do a lot of fetching,
* then ixisect should win.
*/
class PlanRankingIxisectCovered : public PlanRankingTestBase {
public:
void run() {
// Neither 'a' nor 'b' is selective.
for (int i = 0; i < N; ++i) {
insert(BSON("a" << 1 << "b" << 1));
}
// Add indices on 'a' and 'b'.
addIndex(BSON("a" << 1));
addIndex(BSON("b" << 1));
// Query {a:1, b:1}, and project out all fields other than 'a' and 'b'.
CanonicalQuery* cq;
ASSERT(CanonicalQuery::canonicalize(ns,
BSON("a" << 1 << "b" << 1),
BSONObj(),
BSON("_id" << 0 << "a" << 1 << "b" << 1),
&cq).isOK());
ASSERT(NULL != cq);
std::unique_ptr<CanonicalQuery> killCq(cq);
// We should choose an ixisect plan because it requires fewer fetches.
// Takes ownership of cq.
QuerySolution* soln = pickBestPlan(cq);
ASSERT(QueryPlannerTestLib::solutionMatches(
"{proj: {spec: {_id:0,a:1,b:1}, node: {andSorted: {nodes: ["
"{ixscan: {filter: null, pattern: {a:1}}},"
"{ixscan: {filter: null, pattern: {b:1}}}]}}}}",
soln->root.get()));
}
};
/**
* Use the same data, same indices, and same query as the previous
* test case, except without the projection. The query is not covered
* by the index in this case, which means that there is no advantage
* to an index intersection solution.
*/
class PlanRankingIxisectNonCovered : public PlanRankingTestBase {
public:
void run() {
// Neither 'a' nor 'b' is selective.
for (int i = 0; i < N; ++i) {
insert(BSON("a" << 1 << "b" << 1));
}
// Add indices on 'a' and 'b'.
addIndex(BSON("a" << 1));
addIndex(BSON("b" << 1));
// Query {a:1, b:1}.
CanonicalQuery* cq;
ASSERT(CanonicalQuery::canonicalize(ns,
BSON("a" << 1 << "b" << 1),
&cq).isOK());
ASSERT(NULL != cq);
std::unique_ptr<CanonicalQuery> killCq(cq);
// The intersection is large, and ixisect does not make the
// query covered. We should NOT choose an intersection plan.
QuerySolution* soln = pickBestPlan(cq);
bool bestIsScanOverA = QueryPlannerTestLib::solutionMatches(
"{fetch: {node: {ixscan: {pattern: {a: 1}}}}}",
soln->root.get());
bool bestIsScanOverB = QueryPlannerTestLib::solutionMatches(
"{fetch: {node: {ixscan: {pattern: {b: 1}}}}}",
soln->root.get());
ASSERT(bestIsScanOverA || bestIsScanOverB);
}
};
/**
* Index intersection solutions may require fewer fetches even if it does not make the
* query covered. The ixisect plan will scan as many index keys as the union of the two
* single index plans, but only needs to retrieve full documents for the intersection
* of the two plans---this could mean fewer fetches!
*/
class PlanRankingNonCoveredIxisectFetchesLess : public PlanRankingTestBase {
public:
void run() {
// Set up data so that the following conditions hold:
// 1) Documents matching {a: 1} are of high cardinality.
// 2) Documents matching {b: 1} are of high cardinality.
// 3) Documents matching {a: 1, b: 1} are of low cardinality---
// the intersection is small.
// 4) At least one of the documents in the intersection is
// returned during the trial period.
insert(BSON("a" << 1 << "b" << 1));
for (int i = 0; i < N/2; ++i) {
insert(BSON("a" << 1 << "b" << 2));
}
for (int i = 0; i < N/2; ++i) {
insert(BSON("a" << 2 << "b" << 1));
}
// Add indices on 'a' and 'b'.
addIndex(BSON("a" << 1));
addIndex(BSON("b" << 1));
// Neither the predicate on 'b' nor the predicate on 'a' is
// very selective: both retrieve about half the documents.
// However, the intersection is very small, which makes
// the intersection plan desirable.
CanonicalQuery* cq;
ASSERT(CanonicalQuery::canonicalize(ns,
fromjson("{a: 1, b: 1}"),
&cq).isOK());
ASSERT(NULL != cq);
std::unique_ptr<CanonicalQuery> killCq(cq);
QuerySolution* soln = pickBestPlan(cq);
ASSERT(QueryPlannerTestLib::solutionMatches(
"{fetch: {node: {andSorted: {nodes: ["
"{ixscan: {filter: null, pattern: {a:1}}},"
"{ixscan: {filter: null, pattern: {b:1}}}]}}}}",
soln->root.get()));
}
};
/**
* If the intersection is small, an AND_SORTED plan may be able to
* hit EOF before the single index plans.
*/
class PlanRankingIxisectHitsEOFFirst : public PlanRankingTestBase {
public:
void run() {
// Set up the data so that for the query {a: 1, b: 1}, the
// intersection is empty. The single index plans have to do
// more fetching from disk in order to determine that the result
// set is empty. As a result, the intersection plan hits EOF first.
for (int i = 0; i < 30; ++i) {
insert(BSON("a" << 1 << "b" << 2));
}
for (int i = 0; i < 30; ++i) {
insert(BSON("a" << 2 << "b" << 1));
}
for (int i = 0; i < N; ++i) {
insert(BSON("a" << 2 << "b" << 2));
}
// Add indices on 'a' and 'b'.
addIndex(BSON("a" << 1));
addIndex(BSON("b" << 1));
CanonicalQuery* cq;
ASSERT(CanonicalQuery::canonicalize(ns,
fromjson("{a: 1, b: 1}"),
&cq).isOK());
ASSERT(NULL != cq);
std::unique_ptr<CanonicalQuery> killCq(cq);
// Choose the index intersection plan.
QuerySolution* soln = pickBestPlan(cq);
ASSERT(QueryPlannerTestLib::solutionMatches(
"{fetch: {node: {andSorted: {nodes: ["
"{ixscan: {filter: null, pattern: {a:1}}},"
"{ixscan: {filter: null, pattern: {b:1}}}]}}}}",
soln->root.get()));
}
};
/**
* If we query on 'a', 'b', and 'c' with indices on all three fields,
* then there are three possible size-2 index intersections to consider.
* Make sure we choose the right one.
*/
class PlanRankingChooseBetweenIxisectPlans : public PlanRankingTestBase {
public:
void run() {
// Set up the data so that for the query {a: 1, b: 1, c: 1}, the intersection
// between 'b' and 'c' is small, and the other intersections are larger.
for (int i = 0; i < 10; ++i) {
insert(BSON("a" << 1 << "b" << 1 << "c" << 1));
}
for (int i = 0; i < 10; ++i) {
insert(BSON("a" << 2 << "b" << 1 << "c" << 1));
}
for (int i = 0; i < N/2; ++i) {
insert(BSON("a" << 1 << "b" << 1 << "c" << 2));
insert(BSON("a" << 1 << "b" << 2 << "c" << 1));
}
// Add indices on 'a', 'b', and 'c'.
addIndex(BSON("a" << 1));
addIndex(BSON("b" << 1));
addIndex(BSON("c" << 1));
CanonicalQuery* cq;
ASSERT(CanonicalQuery::canonicalize(ns,
fromjson("{a: 1, b: 1, c: 1}"),
&cq).isOK());
ASSERT(NULL != cq);
std::unique_ptr<CanonicalQuery> killCq(cq);
// Intersection between 'b' and 'c' should hit EOF while the
// other plans are busy fetching documents.
QuerySolution* soln = pickBestPlan(cq);
ASSERT(QueryPlannerTestLib::solutionMatches(
"{fetch: {node: {andSorted: {nodes: ["
"{ixscan: {filter: null, pattern: {b:1}}},"
"{ixscan: {filter: null, pattern: {c:1}}}]}}}}",
soln->root.get()));
}
};
/**
* When no other information is available, prefer solutions without
* a blocking sort stage.
@ -835,12 +624,6 @@ namespace PlanRankingTests {
add<PlanRankingPreferImmediateEOFAgainstHashed>();
add<PlanRankingNoCollscan>();
add<PlanRankingCollscan>();
// TODO: These don't work without counting FETCH and FETCH is now gone.
// add<PlanRankingIxisectCovered>();
// add<PlanRankingIxisectNonCovered>();
// add<PlanRankingNonCoveredIxisectFetchesLess>();
// add<PlanRankingIxisectHitsEOFFirst>();
// add<PlanRankingChooseBetweenIxisectPlans>();
add<PlanRankingAvoidBlockingSort>();
add<PlanRankingWorkPlansLongEnough>();
add<PlanRankingAccountForKeySkips>();