postgresql – What are some good Auto vacuuming starting points Postgres? for high write,high update,and mostly read table types?

What are good Auto Vacuum settings (Recommendations) for tables like

  • High Write Table Insert load that range between 30-10,000 inserts in a day the table can idle in weeks without load but can get burst of insert at least 3 times in a week

  • High Update Table it Uses Partition table data is 3-8 times the size of my table from a single insert High Write Table a single row gets updated only ones but burst of unique key update in a day
    and needs to be updated it could be 30-10,000 key update

  • High Read Table Most tables are high Read Table set to Fill Factor 80 for my data warehouse housing table that came from the computation of High Update Table

  • My Delete happens in monthly and in batches everything relating to the key gets deleted or moved as backup

currently my FillFactor is set to be 10-20 for high update table

using rds db.t3.large but i switch to db.t3.micro when during low traffic

Additional Question does setting FillFactor to really low slow down select?

foreign key – Postgresql Create ForeignKey with repeated table name in value of ref contrain key

I am working on a database which does not contain any foreign key. When i open table I see strange format key because table of parent reference is stored in the value.

exemple

CREATE TABLE foo 
  ( 
  id SERIAL,
  name text
  );

CREATE TABLE bar
  ( 
  id SERIAL,
  foo_id text,
  name text
  );

INSERT INTO foo("name")
VALUES ('john');

INSERT INTO bar("foo_id","name")
VALUES (CONCAT('foo.'|| 1),'doe');
INSERT INTO bar("foo_id","name")
VALUES (CONCAT('foo.'|| 1),'kelly');

Can I create an FK with this type of structure? I have never seen this before

database design – Common `event` (datetime) table for say a manufacturing DB, bad idea?

There are many different types of events that can happen during a manufacturing process.
E.g.

  • Built Step1
  • Build Step2
  • Test
  • Checked into repairs
  • Checkout out of repairs
  • Packaged
  • Dspatched, etc.

I see two ways to model each step:

  1. Have separate independant tables. Each table with its own timestamp field.
  2. Extract the timestamp field from the tables, and place it in a common event tables which has say 2 fields:
    • timestamp field
    • A column which links it to which type of event it is (which table has the specific details for that type of event).
    • Could also have a user field to track who did what etc.

Any reasons why not to use way 2 (event table)? It seems advantages for running reports on what events happened during a certain time frame. A way of uniting events in the factory. But my research seems to always point towards avoiding any common function tables.

What are the pros/cons of between these 2 database design options where the join table can have 2 or 3 foreign keys?

I am trying to model the following scenario, but I have come up with 2 options and I cannot figure out how to decide between the 2 options. Both options seem to work, but I worry that I am missing some edge case that suggests one over the other. Any recommendations or suggestions on where one option might be better than the other option?

Thank you for your time 🙂

The model:

A user has many labels
A property has many labels
A label has many properties

Option 1 (join table with 2 foreign keys):

user
----
id
name

property
--------
id
name

label
-----
id
name
user_id (foreign key for user.id)

property_label
--------------
property_id (foreign key for property.id)
label_id (foreign key for label.id)

Option 2 (join table with 3 foreign keys):

user
----
id
name

property
--------
id
name

label
-----
id
name

user_property_label
-------------------
property_id (foreign key for property.id)
label_id (foreign key for label.id)
user_id (foreign key for user.id)

Potential Queries:

Get all labels associated with a user
Get all properties associated with a label of a user

Example data:

User1 has labels "old" and "new" for property "bicycle".
User2 has labels "1 year", "2 years", and "3+ years" for property "bicycle".
User 3 has labels "<3 years" and "3+ years" for property "car"
User 4 has labels "red", "blue", and "black" for property "car"
User 5 has labels "daily beater" and "weekend fun" for property "car" and labels "<3 years" and "3+ years" for property "bicycle"
User 6 has labels "1 year", "2 years", and "3+ years" for properties "bicycle" and "car"

The list of properties is large, but finite. Users will reference the same property and cannot have their own variation in its spelling. So for example, “bicycle” will always be “bicycle” for every user. A user cannot have “bike” or “bi-cycle” or some other spelling of the property.

The labels are all user defined so it can be infinite depending on how each individual user wants to label their properties.

Using Table to iterate over two lists element by element instead of as a matrix

So I have two lists generated in the following fashion, I don’t know if it’s the most efficent way to get these, but that’s beside the point right now.

Nlayer = 6;
n = 0;
layernumber = Table(n = n + (Mod(i, 2)), {i, 1, 2*Nlayer})
n = 1;
interfacenumber = Table(n = n + (Mod(i, 2)), {i, 0, 2*Nlayer-1})

Which returns:

{1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6}

{1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7}

And I’m trying to get the Table function to apply the i-th value of each list to two different functions X and Y, getting a list of the same length as above. What I have right now is the following (which is incorrect, it returns a 12×12 matrix instead of a 1×12 table):

Table(X(i)*Y(j), {i,layernumber}, {j,interfacenumber});

In other words, I want it to return the 12 values that would be computed below into a list. Later, this will be expanded well beyond 12 values and I want to just expand the initial list instead of typing this out many more times.

X(1)*Y(1)
X(1)*Y(2)
X(2)*Y(2)
X(2)*Y(3)
X(3)*Y(3)
X(3)*Y(4)
X(4)*Y(4)
X(4)*Y(5)
X(5)*Y(5)
X(5)*Y(6)
X(6)*Y(6)
X(6)*Y(7)

Thank you in advance for answers, I’m headed to bed and will respond in the morning.

theming – creating a custom report page with a table

Yeah I think you’re conflating a few different concepts and making everything way more complex than it needs to be.

If you all you want to do is render a particular custom template with your controller then you’d want to:

// In fun.module
function fun_theme() {
  return (
    'a_fun_template' => (
      'variables' => (
        'heading' => '',
        'activities' => ()
      ),
    ),
}

// Then in your controller
public function yourRenderMethod() {
  $heading = 'Some fun activities';
  $activities = (
     'Rocket League',
     'Violin'
  );
  return (
    '#theme' => 'a_fun_template',
    '#heading' => $heading,
    '#activities' => $activities, 
  );
}

// Then in a-fun-template.html.twig
{#
  Do whatever with your variables, like print them
#}
<h1>{{ heading }}</h1>
<ul>
{% for activity in activities %}
  <li>{{ activity }}</li>
{% endfor %}
</ul>

EDIT: I think I figured out why you’re looking at the block. All that that is is the “Main page content” block from the blocks page. This just renders the main content for the page, which in this case would be the contents of your controller’s template. Now that said, what I wrote before was…

I really don’t understand where the block is coming into play here, but I think you’re misunderstanding that as well.

First, the default template suggestions are very general. block--wd-admin-content.html.twig is probably added by wd_admin to every admin block by default. That’s why a template by that name would be used by all blocks in the admin area. Generally the longer the suggested template name, the more specific it is. Template suggestions that you add to hook_theme_suggestions_block_alter() will apply to all blocks unless you wrap the suggestion in conditional logic that says otherwise. If all you’re doing is using a hook_theme template in a controller then you don’t need this hook at all.

t sql – Yet another SQL Server calendar table question

After the wonderful help I received on my original question, we have discovered that our current method of calculating our fiscal calendar is wrong.

Fiscal calendar rules:

  • fiscal year starts 2 calendar days after the last Friday of October
  • fiscal year ends on the last Friday of October
  • no business is conducted on Saturday
  • fiscal calendar runs Sunday to Saturday
  • there are 13 fiscal periods in the fiscal year
  • there are 4 weeks in each fiscal period, with the exception of the 13th fiscal period, which allows for an extra week

Using Aaron Bertrand’s calendar table, I have been able to identify the start of the fiscal periods as:

;WITH
LastFridayInOctober AS(
    SELECT YEAR(TheDate) 'TheYear',
            TheMonth,
            TheDayOfWeek,
            MAX(TheDayOfWeekInMonth) 'LastFriday'
    FROM dbo.DateDimension
    WHERE TheMonth = 10
        AND TheDayOfWeek = 6
    GROUP BY YEAR(TheDate),
                TheMonth,
                TheDayOfWeek
)

-- fiscal year start dates
SELECT DD.TheDate,
        LFIO.TheYear,
        LFIO.TheMonth,
        LFIO.TheDayOfWeek,
        LFIO.LastFriday,
        YEAR(DD.TheDate) + 1 'NextFiscalYear',
        DATEADD(day, 2, DD.TheDate) 'NextFiscalYearStart',
        DATENAME(weekday, DATEADD(day, 2, DD.TheDate)) 'NextFiscalYearStartDayName',
        '' 'NextFiscalYearEndDate',
        '' NextFiscalYearStartDayName       
FROM dbo.DateDimension DD
    INNER JOIN LastFridayInOctober LFIO ON DD.TheYear = LFIO.TheYear
        AND DD.TheMonth = LFIO.TheMonth
        AND DD.TheDayOfWeek = LFIO.TheDayOfWeek
        AND DD.TheDayOfWeekInMonth = LFIO.LastFriday
ORDER BY DD.TheDate;


TheDate..........TheYear..........TheMonth..........TheDayOfWeek..........LastFriday..........NextFiscalYear..........NextFiscalYearStart..........NextFiscalYearStartDayName..........NextFiscalYearEndDate..........NextFiscalYearStartDayName
1921-10-28       1921             10                6                     4                   1922                    1921-10-30                   Sunday                              <should be 1922-10-28>         <Saturday>
1922-10-27       1922             10                6                     4                   1923                    1922-10-29                   Sunday                              <should be 1922-10-27>         <Saturday>
1923-10-26       1923             10                6                     4                   1924                    1923-10-28                   Sunday                              <should be 1922-11-02>         <Saturday>
1924-10-31       1924             10                6                     5                   1925                    1924-11-02                   Sunday                              <should be 1922-11-01>         <Saturday>
1925-10-30       1925             10                6                     5                   1926                    1925-11-01                   Sunday                              <should be 1922-10-31>         <Saturday>
1926-10-29       1926             10                6                     5                   1927                    1926-10-31                   Sunday                              <should be 1922-10-30>         <Saturday>

If I can get the last Friday of October for the next year in the same query, I am sure I can break down my calendar data into the proper fiscal weeks and periods, but I just cant’ seem to get it. I’m sure the answer is staring me right in the face.

postgresql – How I can find the most resource-intensive queries that has ever run in my database and use a specific table?

In my database I want to check whether my idea on an improvement upon table schema works. Therefore I want so look which are the heaviest select queries ever run into our database and use a specific table that I want to do the changes.

My idea is to check the speed and database load of our heaviest queries in my database, then do the schema changes (or possible query refactoring as well) and rerun them so I can benchmark my idea with real data.

Hence I can have a proof that my changes actually improve search speed.

So how I can search which queries upon a postgresql RDS instance even run and how heavy they are?

Why MyBatis query big table timeout but fast in Sequel Pro in MySQL 5.7

I am using MySQL 5.7, today this is a long time query stuck me. this is my table DML:

CREATE TABLE `h_round_pump_record` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '',
  `tenant_id` bigint(20) NOT NULL COMMENT '',
  `tenant_name` varchar(256) NOT NULL DEFAULT '' COMMENT '',
  `created_time` bigint(20) NOT NULL COMMENT '',
  `updated_time` bigint(20) NOT NULL COMMENT '',
  `app_id` bigint(11) NOT NULL COMMENT '',
  `app_mark` varchar(256) NOT NULL DEFAULT '' COMMENT '',
  `app_name` varchar(256) NOT NULL DEFAULT '' COMMENT '',
  `settlement_time` bigint(20) NOT NULL COMMENT '',
  `biz_id` bigint(20) NOT NULL COMMENT '',
  `room_play_id` bigint(20) NOT NULL COMMENT '',
  `room_amount_fmt` varchar(256) NOT NULL DEFAULT '' COMMENT '',
  `tenant_revenue` bigint(20) GENERATED ALWAYS AS ((`real_people_revenue` + `robot_profit`)) STORED,
  PRIMARY KEY (`id`),
  UNIQUE KEY `biz_id` (`biz_id`,`tenant_id`,`app_id`),
  KEY `round_record_idx` (`settlement_time`,`having_real_people`,`tenant_id`,`app_id`)
) ENGINE=InnoDB AUTO_INCREMENT=907725 DEFAULT CHARSET=utf8mb4;

and this is my query sql:

select *
    from h_round_pump_record 
     WHERE (  settlement_time <= 1601481599000
                  and settlement_time >= 1598889600000
                  and tenant_id = 
                  and app_id in
                  (
                    1
        ) )

to speed up query, I create a index in settlement_time. In Sequel Pro the SQL will return result in 3 seconds, but In apps query using MyBatis, it will take 30s to return, why the MyBatis query takes so long(the sql is the same because I am copied from slow_log table)? This is my slow log settings:

set global slow_query_log=ON
set global log_output='table';
set long_query_time = 5;
select * 
from mysql.slow_log;

this is the log output of MyBatis:

org.springframework.dao.QueryTimeoutException: 
### Error querying database.  Cause: com.mysql.cj.jdbc.exceptions.MySQLTimeoutException: Statement cancelled due to timeout or client request
### The error may exist in class path resource (mybatis/mapper/illidan/RoundPumpRecordMapper.xml)
### The error may involve com.sportswin.soa.illidan.hub.dao.RoundPumpRecordMapper.selectByExample-Inline
### The error occurred while setting parameters
### SQL: select           'true' as QUERYID,                id, tenant_id, tenant_name, agent_id, agent_name, created_time, updated_time, app_id,      app_mark, app_name, settlement_time, biz_id, room_play_id, room_amount_fmt, ratio,      tenant_revenue, real_pump_amount, real_people_profit, robot_profit, robot_revenue,      real_people_revenue, having_real_people         from h_round_pump_record                         WHERE (  settlement_time <= ?                                                                and settlement_time >= ?                                                                and tenant_id = ?                                                                and app_id in                   (                     ?                   ) )
### Cause: com.mysql.cj.jdbc.exceptions.MySQLTimeoutException: Statement cancelled due to timeout or client request
; Statement cancelled due to timeout or client request; nested exception is com.mysql.cj.jdbc.exceptions.MySQLTimeoutException: Statement cancelled due to timeout or client request
    at org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:76) ~(spring-jdbc-5.1.13.RELEASE.jar!/:5.1.13.RELEASE)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72) ~(spring-jdbc-5.1.13.RELEASE.jar!/:5.1.13.RELEASE)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81) ~(spring-jdbc-5.1.13.RELEASE.jar!/:5.1.13.RELEASE)
    at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:74) ~(mybatis-spring-2.0.2.jar!/:2.0.2)
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:440) ~(mybatis-spring-2.0.2.jar!/:2.0.2)
    at com.sun.proxy.$Proxy178.selectList(Unknown Source) ~(na:na)
    at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:223) ~(mybatis-spring-2.0.2.jar!/:2.0.2)
    at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:147) ~(mybatis-3.5.2.jar!/:3.5.2)
    at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:80) ~(mybatis-3.5.2.jar!/:3.5.2)
    at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:57) ~(mybatis-3.5.2.jar!/:3.5.2)
    at com.sun.proxy.$Proxy187.selectByExample(Unknown Source) ~(na:na)
    at com.sportswin.soa.illidan.hub.service.impl.HubRoundPumpRecordService.lambda$page$0(HubRoundPumpRecordService.java:63) ~(classes!/:na)
    at com.github.pagehelper.Page.doSelectPageInfo(Page.java:353) ~(pagehelper-5.1.11.jar!/:na)
    at com.sportswin.soa.illidan.hub.service.impl.HubRoundPumpRecordService.page(HubRoundPumpRecordService.java:62) ~(classes!/:na)
    at com.sportswin.soa.illidan.hub.common.HubCommonUtil.getRoundPump(HubCommonUtil.java:164) ~(classes!/:na)
    at com.sportswin.soa.illidan.hub.common.HubScheduleTask.generateImpl(HubScheduleTask.java:177) ~(classes!/:na)
    at com.sportswin.soa.illidan.hub.common.HubScheduleTask.generateFilesTask(HubScheduleTask.java:159) ~(classes!/:na)
    at com.sportswin.soa.illidan.hub.common.HubScheduleTask.lambda$generateExportFile$0(HubScheduleTask.java:103) ~(classes!/:na)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~(na:1.8.0_212)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~(na:1.8.0_212)
    at com.sportswin.soa.misc.config.async.pool.MdcTaskDecorator.lambda$decorate$0(MdcTaskDecorator.java:31) ~(soa-misc-1.0.0-SNAPSHOT.jar!/:na)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~(na:1.8.0_212)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~(na:1.8.0_212)
    at java.lang.Thread.run(Thread.java:748) ~(na:1.8.0_212)
Caused by: com.mysql.cj.jdbc.exceptions.MySQLTimeoutException: Statement cancelled due to timeout or client request
    at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:113) ~(mysql-connector-java-8.0.19.jar!/:8.0.19)
    at com.mysql.cj.jdbc.StatementImpl.checkCancelTimeout(StatementImpl.java:2191) ~(mysql-connector-java-8.0.19.jar!/:8.0.19)
    at com.mysql.cj.protocol.a.NativeProtocol.sendQueryPacket(NativeProtocol.java:1020) ~(mysql-connector-java-8.0.19.jar!/:8.0.19)
    at com.mysql.cj.NativeSession.execSQL(NativeSession.java:1075) ~(mysql-connector-java-8.0.19.jar!/:8.0.19)
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:930) ~(mysql-connector-java-8.0.19.jar!/:8.0.19)
    at com.mysql.cj.jdbc.ClientPreparedStatement.execute$original$zlbDqAbk(ClientPreparedStatement.java:370) ~(mysql-connector-java-8.0.19.jar!/:8.0.19)
    at com.mysql.cj.jdbc.ClientPreparedStatement.execute$original$zlbDqAbk$accessor$77RRWgJE(ClientPreparedStatement.java) ~(mysql-connector-java-8.0.19.jar!/:8.0.19)
    at com.mysql.cj.jdbc.ClientPreparedStatement$auxiliary$WZ5P0ECx.call(Unknown Source) ~(mysql-connector-java-8.0.19.jar!/:8.0.19)
    at org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstMethodsInter.intercept(InstMethodsInter.java:93) ~(skywalking-agent.jar:6.5.0)
    at com.mysql.cj.jdbc.ClientPreparedStatement.execute(ClientPreparedStatement.java) ~(mysql-connector-java-8.0.19.jar!/:8.0.19)
    at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_execute(FilterChainImpl.java:3051) ~(druid-1.1.9.jar!/:1.1.9)
    at com.alibaba.druid.filter.FilterAdapter.preparedStatement_execute(FilterAdapter.java:1080) ~(druid-1.1.9.jar!/:1.1.9)
    at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_execute(FilterChainImpl.java:3049) ~(druid-1.1.9.jar!/:1.1.9)
    at com.alibaba.druid.filter.FilterEventAdapter.preparedStatement_execute(FilterEventAdapter.java:440) ~(druid-1.1.9.jar!/:1.1.9)
    at com.alibaba.druid.filter.FilterChainImpl.preparedStatement_execute(FilterChainImpl.java:3049) ~(druid-1.1.9.jar!/:1.1.9)
    at com.alibaba.druid.proxy.jdbc.PreparedStatementProxyImpl.execute(PreparedStatementProxyImpl.java:167) ~(druid-1.1.9.jar!/:1.1.9)
    at com.alibaba.druid.pool.DruidPooledPreparedStatement.execute(DruidPooledPreparedStatement.java:498) ~(druid-1.1.9.jar!/:1.1.9)
    at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:64) ~(mybatis-3.5.2.jar!/:3.5.2)
    at org.apache.ibatis.executor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:79) ~(mybatis-3.5.2.jar!/:3.5.2)
    at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:63) ~(mybatis-3.5.2.jar!/:3.5.2)
    at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:324) ~(mybatis-3.5.2.jar!/:3.5.2)
    at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156) ~(mybatis-3.5.2.jar!/:3.5.2)
    at sun.reflect.GeneratedMethodAccessor237.invoke(Unknown Source) ~(na:na)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~(na:1.8.0_212)
    at java.lang.reflect.Method.invoke(Method.java:498) ~(na:1.8.0_212)
    at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:63) ~(mybatis-3.5.2.jar!/:3.5.2)
    at com.sun.proxy.$Proxy254.query(Unknown Source) ~(na:na)
    at sun.reflect.GeneratedMethodAccessor237.invoke(Unknown Source) ~(na:na)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~(na:1.8.0_212)
    at java.lang.reflect.Method.invoke(Method.java:498) ~(na:1.8.0_212)
    at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:63) ~(mybatis-3.5.2.jar!/:3.5.2)
    at com.sun.proxy.$Proxy254.query(Unknown Source) ~(na:na)
    at com.github.pagehelper.util.ExecutorUtil.pageQuery(ExecutorUtil.java:180) ~(pagehelper-5.1.11.jar!/:na)
    at com.github.pagehelper.PageInterceptor.intercept(PageInterceptor.java:104) ~(pagehelper-5.1.11.jar!/:na)
    at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:61) ~(mybatis-3.5.2.jar!/:3.5.2)
    at com.sun.proxy.$Proxy254.query(Unknown Source) ~(na:na)
    at sun.reflect.GeneratedMethodAccessor263.invoke(Unknown Source) ~(na:na)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~(na:1.8.0_212)
    at java.lang.reflect.Method.invoke(Method.java:498) ~(na:1.8.0_212)
    at org.apache.ibatis.plugin.Invocation.proceed(Invocation.java:49) ~(mybatis-3.5.2.jar!/:3.5.2)
    at tk.mybatis.orderbyhelper.OrderByHelper.intercept(OrderByHelper.java:115) ~(orderby-helper-0.0.2.jar!/:na)
    at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:61) ~(mybatis-3.5.2.jar!/:3.5.2)
    at com.sun.proxy.$Proxy254.query(Unknown Source) ~(na:na)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147) ~(mybatis-3.5.2.jar!/:3.5.2)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:140) ~(mybatis-3.5.2.jar!/:3.5.2)
    at sun.reflect.GeneratedMethodAccessor414.invoke(Unknown Source) ~(na:na)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~(na:1.8.0_212)
    at java.lang.reflect.Method.invoke(Method.java:498) ~(na:1.8.0_212)
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:426) ~(mybatis-spring-2.0.2.jar!/:2.0.2)
    ... 19 common frames omitted