Uploaded image for project: 'Phoenix'
  1. Phoenix
  2. PHOENIX-5752

Phoenix RVC InListExpression generates wrong DESC order column scan

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Resolved
    • Major
    • Resolution: Resolved
    • None
    • None
    • None

    Description

      @Test
      public void testInListExpressionWithDescOrderWithRightQueryPlan() throws Exception {
          String fullTableName = generateUniqueName();
          String fullViewName = generateUniqueName();
          String tenantView = generateUniqueName();
          String TENANT_SPECIFIC_URL1 = getUrl() + ';' + TENANT_ID_ATTRIB + "=tenant1";
      
          try (Connection conn = DriverManager.getConnection(getUrl())) {
              conn.setAutoCommit(true);
              try (Statement stmt = conn.createStatement()) {
                  stmt.execute("CREATE TABLE " + fullTableName + "(\n" + " TENANT_ID CHAR(15) NOT NULL,\n" + " KEY_PREFIX CHAR(3) NOT NULL,\n" +
                          " CONSTRAINT PK PRIMARY KEY (\n" + " TENANT_ID," + " KEY_PREFIX" + ")) MULTI_TENANT=TRUE");
                  stmt.execute("CREATE VIEW " + fullViewName + "(\n" + " ID1 VARCHAR NOT NULL,\n" + " ID2 VARCHAR NOT NULL,\n" + " ID3 BIGINT, ID4 BIGINT \n" +
                          " CONSTRAINT PKVIEW PRIMARY KEY\n" + " (\n" + " ID1, ID2 DESC\n" + ")) " +
                          "AS SELECT * FROM " + fullTableName + " WHERE KEY_PREFIX = '0CY'");
              }
          }
      
          try (Connection viewConn = DriverManager.getConnection(TENANT_SPECIFIC_URL1)) {
              viewConn.setAutoCommit(true);
              try (Statement stmt = viewConn.createStatement()) {
                  stmt.execute("CREATE VIEW IF NOT EXISTS " + tenantView + " AS SELECT * FROM " + fullViewName);
      
                  try (PreparedStatement preparedStmt = viewConn.prepareStatement(
                          "SELECT * FROM " + tenantView + " WHERE (ID1, ID2) " +
                                  "IN (('me', '000000000000500')," +
                                  "('bar', '000000000000400')," +
                                  "('foo', '000000000000300'))")) {
                      QueryPlan queryPlan = PhoenixRuntime.getOptimizedQueryPlan(preparedStmt);
                      assertTrue(queryPlan.getExplainPlan().toString().contains("POINT LOOKUP ON "));
                  }
              }
          }
      }
      

      InListExpression generates a range scan instead of a point lookup. This might result in an extremely bad performance for the DELETE and SELECT query. From my perspective, it might be the point that we need to refactor and/or rewrite query optimization code so that we don't need to have two code paths for InListExpresson. We can simply do the query rewrite to ((ID1=? AND ID2=?) or (ID1=? AND  ID2=?)) as the right approach. 

      Attachments

        Activity

          People

            yanxinyi Xinyi Yan
            yanxinyi Xinyi Yan
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: