slow_select.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:5k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. #include <NdbApi.hpp>
  2. #include <NdbOut.hpp>
  3. #include <NdbTick.h>
  4. struct
  5. S_Scan {
  6.   const char * m_table;
  7.   const char * m_index;
  8.   NdbIndexScanOperation * m_scan;
  9.   NdbResultSet * m_result;
  10.   Uint32 metaid;
  11.   Uint32 match_count;
  12.   Uint32 row_count;
  13. };
  14. static S_Scan g_scans[] = {
  15.   { "affiliatestometa", "ind_affiliatestometa", 0, 0, 0, 0, 0 },
  16.   { "media", "metaid", 0, 0, 0, 0, 0 },
  17.   { "meta", "PRIMARY", 0, 0, 0, 0, 0 },
  18.   { "artiststometamap", "PRIMARY", 0, 0, 0, 0, 0 },
  19.   { "subgenrestometamap", "metaid", 0, 0, 0, 0, 0 }
  20. };
  21. #define require(x) if(!(x)) { ndbout << "LINE: " << __LINE__ << endl;abort(); }
  22. #define require2(o, x) if(!(x)) { ndbout << o->getNdbError() << endl; abort(); }
  23. Uint32 g_affiliateid = 2;
  24. Uint32 g_formatids[] = { 8, 31, 76 };
  25. Uint64 start;
  26. Uint32 g_artistid = 0;
  27. Uint32 g_subgenreid = 0;
  28. NdbConnection* g_trans =  0;
  29. static void lookup();
  30. int
  31. main(void){
  32.   ndb_init();
  33.   Ndb g_ndb("test");
  34.   g_ndb.init(1024);
  35.   require(g_ndb.waitUntilReady() == 0);
  36.   while(true){
  37.     g_trans = g_ndb.startTransaction();
  38.     require(g_trans);
  39.   
  40.     size_t i, j;
  41.     const size_t cnt = sizeof(g_scans)/sizeof(g_scans[0]);
  42.     start = NdbTick_CurrentMillisecond();
  43.     for(i = 0; i<cnt; i++){
  44.       ndbout_c("starting scan on: %s %s", 
  45.        g_scans[i].m_table, g_scans[i].m_index);
  46.       g_scans[i].m_scan = g_trans->getNdbIndexScanOperation(g_scans[i].m_index, 
  47.     g_scans[i].m_table);
  48.       NdbIndexScanOperation* scan = g_scans[i].m_scan;
  49.       require(scan);
  50.       g_scans[i].m_result = scan->readTuples(NdbScanOperation::LM_CommittedRead, 
  51.      0, 0, true);
  52.       require(g_scans[i].m_result);
  53.     }
  54.   
  55.     require(!g_scans[0].m_scan->setBound((Uint32)0, 
  56.  NdbIndexScanOperation::BoundEQ, 
  57.  &g_affiliateid, 
  58.  sizeof(g_affiliateid)));
  59. #if 0
  60.     require(!g_scans[1].m_scan->setBound((Uint32)0, 
  61.  NdbIndexScanOperation::BoundLE,
  62.  &g_formatids[0],
  63.  sizeof(g_formatids[0])));  
  64. #endif
  65.     NdbScanFilter sf(g_scans[1].m_scan);
  66.     sf.begin(NdbScanFilter::OR);
  67.     sf.eq(2, g_formatids[0]);
  68.     sf.eq(2, g_formatids[1]);
  69.     sf.eq(2, g_formatids[2]);
  70.     sf.end();
  71.     // affiliatestometa
  72.     require(g_scans[0].m_scan->getValue("uniquekey"));
  73.     require(g_scans[0].m_scan->getValue("xml"));
  74.     // media
  75.     require(g_scans[1].m_scan->getValue("path"));
  76.     require(g_scans[1].m_scan->getValue("mediaid"));
  77.     require(g_scans[1].m_scan->getValue("formatid"));
  78.   
  79.     // meta
  80.     require(g_scans[2].m_scan->getValue("name"));
  81.     require(g_scans[2].m_scan->getValue("xml"));
  82.     // artiststometamap
  83.     require(g_scans[3].m_scan->getValue("artistid", (char*)&g_artistid));
  84.   
  85.     // subgenrestometamap
  86.     require(g_scans[4].m_scan->getValue("subgenreid", (char*)&g_subgenreid));
  87.   
  88.     for(i = 0; i<cnt; i++){
  89.       g_scans[i].m_scan->getValue("metaid", (char*)&g_scans[i].metaid);
  90.     }
  91.     g_trans->execute(NoCommit, AbortOnError, 1);
  92.     Uint32 max_val = 0;
  93.     Uint32 match_val = 0;
  94.   
  95.     S_Scan * F [5], * Q [5], * nextF [5];
  96.     Uint32 F_sz = 0, Q_sz = 0;
  97.     for(i = 0; i<cnt; i++){
  98.       F_sz++;
  99.       F[i] = &g_scans[i];
  100.     }
  101.     Uint32 match_count = 0;
  102.     while(F_sz > 0){
  103.       Uint32 prev_F_sz = F_sz;
  104.       F_sz = 0;
  105.       bool found = false;
  106.       //for(i = 0; i<cnt; i++)
  107.       //ndbout_c("%s - %d", g_scans[i].m_table, g_scans[i].metaid);
  108.     
  109.       for(i = 0; i<prev_F_sz; i++){
  110. int res = F[i]->m_result->nextResult();
  111. if(res == -1)
  112.   abort();
  113. if(res == 1){
  114.   continue;
  115. }
  116. Uint32 metaid = F[i]->metaid;
  117. F[i]->row_count++;
  118.       
  119. if(metaid == match_val){
  120.   //ndbout_c("flera");
  121.   nextF[F_sz++] = F[i];
  122.   require(F_sz >= 0 && F_sz <= cnt);
  123.   F[i]->match_count++;
  124.   Uint32 comb = 1;
  125.   for(j = 0; j<cnt; j++){
  126.     comb *= (&g_scans[j] == F[i] ? 1 : g_scans[j].match_count);
  127.   }
  128.   match_count += comb;
  129.   found = true;
  130.   continue;
  131. }
  132. if(metaid < max_val){
  133.   nextF[F_sz++] = F[i];
  134.   require(F_sz >= 0 && F_sz <= cnt);
  135.   continue;
  136. }
  137. if(metaid > max_val){
  138.   for(j = 0; j<Q_sz; j++)
  139.     nextF[F_sz++] = Q[j];
  140.   require(F_sz >= 0 && F_sz <= cnt);
  141.   Q_sz = 0;
  142.   max_val = metaid;
  143. }
  144. Q[Q_sz++] = F[i];
  145. require(Q_sz >= 0 && Q_sz <= cnt);
  146.       }
  147.       if(F_sz == 0 && Q_sz > 0){
  148. match_val = max_val;
  149. for(j = 0; j<Q_sz; j++){
  150.   nextF[F_sz++] = Q[j];
  151.   Q[j]->match_count = 1;
  152. }
  153. require(F_sz >= 0 && F_sz <= cnt);
  154. require(Q_sz >= 0 && Q_sz <= cnt);
  155. Q_sz = 0;
  156. match_count++;
  157. lookup();
  158.       } else if(!found && F_sz + Q_sz < cnt){
  159. F_sz = 0;
  160.       }
  161.       require(F_sz >= 0 && F_sz <= cnt);
  162.       for(i = 0; i<F_sz; i++)
  163. F[i] = nextF[i];
  164.     }
  165.   
  166.     start = NdbTick_CurrentMillisecond() - start;
  167.     ndbout_c("Elapsed: %lldms", start);
  168.   
  169.     ndbout_c("rows: %d", match_count);
  170.     for(i = 0; i<cnt; i++){
  171.       ndbout_c("%s : %d", g_scans[i].m_table, g_scans[i].row_count);
  172.     }
  173.     g_trans->close();
  174.   }
  175. }
  176. static
  177. void
  178. lookup(){
  179.   {
  180.     NdbOperation* op = g_trans->getNdbOperation("artists");
  181.     require2(g_trans, op);
  182.     require2(op, op->readTuple() == 0);
  183.     require2(op, op->equal("artistid", g_artistid) == 0);
  184.     require2(op, op->getValue("name"));
  185.   }
  186.   
  187.   {
  188.     NdbOperation* op = g_trans->getNdbOperation("subgenres");
  189.     require2(g_trans, op);
  190.     require2(op, op->readTuple() == 0);
  191.     require2(op, op->equal("subgenreid", g_subgenreid) == 0);
  192.     require2(op, op->getValue("name"));
  193.   }
  194.   static int loop = 0;
  195.   if(loop++ >= 16){
  196.     loop = 0;
  197.     require(g_trans->execute(NoCommit) == 0);
  198.   }
  199.   //require(g_trans->restart() == 0);
  200. }